//{new App() {Id = p.Id}}
        protected override Expression VisitMemberInit(MemberInitExpression node)
        {
            if (node.NewExpression != null)
            {
                this.VisitAllArguments(node.NewExpression);
            }

            if (_navDescriptorKeys.Count == 0)
            {
                _navDescriptorKeys.Add(node.Type.Name);
            }

            //todo #对 Bindings 进行排序,保证导航属性的赋值一定要最后面#
            // 未实现,在书写表达式时人工保证 ##

            for (int i = 0; i < node.Bindings.Count; i++)
            {
                MemberAssignment binding = node.Bindings[i] as MemberAssignment;
                if (binding == null)
                {
                    throw new XfwException("Only 'MemberAssignment' binding supported.");
                }

                Type pType    = (node.Bindings[i].Member as System.Reflection.PropertyInfo).PropertyType;
                bool visitNav = !TypeUtils.IsPrimitive(pType);

                #region 一般属性

                // 非导航属性
                if (!visitNav)
                {
                    base.VisitMemberBinding(node.Bindings[i]);

                    // 选择字段
                    string newName = ColumnExpressionVisitor.AddColumn(_columns, binding.Member.Name);
                    // 添加字段别名
                    _builder.AppendAs(newName);
                    _builder.Append(',');
                    _builder.AppendNewLine();

                    continue;
                }

                #endregion

                #region 导航属性

                int n = _navDescriptorKeys.Count;

                string keyName = _navDescriptorKeys.Count > 0 ? _navDescriptorKeys[_navDescriptorKeys.Count - 1] : string.Empty;
                keyName = !string.IsNullOrEmpty(keyName) ? keyName + "." + binding.Member.Name : binding.Member.Name;
                ColumnNavDescriptor descriptor = new ColumnNavDescriptor(keyName, binding.Member);

                if (!_navDescriptors.ContainsKey(keyName))
                {
                    descriptor.Start = _columns.Count;
                    descriptor.Count = CountField(binding.Expression);
                    _navDescriptors.Add(keyName, descriptor);
                    _navDescriptorKeys.Add(keyName);
                }

                if (binding.Expression.NodeType == ExpressionType.MemberAccess)
                {
                    this.VisitMember_Navigation(binding.Expression as MemberExpression);
                }
                else if (binding.Expression.NodeType == ExpressionType.New)
                {
                    this.VisitAllArguments(binding.Expression as NewExpression);
                }
                else if (binding.Expression.NodeType == ExpressionType.MemberInit)
                {
                    this.VisitMemberInit(binding.Expression as MemberInitExpression);
                }

                if (_navDescriptorKeys.Count != n)
                {
                    _navDescriptorKeys.RemoveAt(_navDescriptorKeys.Count - 1);
                }

                #endregion
            }

            return(node);
        }
示例#2
0
        // 导航属性
        private static void ToModel_Navigation(object model, object[] values, CommandDefine_Select define, string typeName)
        {
            // CRM_SaleOrder.Client
            Type            pType   = model.GetType();
            TypeRuntimeInfo runtime = TypeRuntimeInfoCache.GetRuntimeInfo(pType);

            if (string.IsNullOrEmpty(typeName))
            {
                typeName = pType.Name;
            }

            foreach (var kvp in runtime.NavWrappers)
            {
                string keyName = typeName + "." + kvp.Key;
                ColumnNavDescriptor descriptor = null;
                define.NavDescriptors.TryGetValue(keyName, out descriptor);
                if (descriptor == null)
                {
                    continue;
                }

                // 实例化这个导航属性并且给它赋值
                var             navWrapper = kvp.Value;
                Type            navType    = navWrapper.DataType;
                TypeRuntimeInfo navRuntime = TypeRuntimeInfoCache.GetRuntimeInfo(navType);
                object          navModel   = navRuntime.ConstructInvoker.Invoke();

                if (descriptor.Count > 0)
                {
                    int index = -1;
                    foreach (var c_kvp in define.Columns)
                    {
                        index += 1;
                        if (index < descriptor.Start)
                        {
                            continue;
                        }
                        if (index > (descriptor.Start + descriptor.Count))
                        {
                            break;
                        }

                        object obj = values[index];
                        if (obj == DBNull.Value)
                        {
                            continue;
                        }

                        var wrapper = navRuntime.GetWrapper(c_kvp.Value.Name) as MemberAccessWrapper;
                        if (wrapper != null)
                        {
                            SetProperty(navModel, wrapper, obj);
                        }
                    }
                }

                SetProperty(model, navWrapper, navModel);

                if (navRuntime.NavWrappers.Count > 0)
                {
                    ToModel_Navigation(navModel, values, define, keyName);
                }
            }
        }