Пример #1
0
        // => Name = "Name"
        private void VisitMemberAssignmentImpl(Type newType, MemberAssignment m)
        {
            // 先添加当前字段的访问痕迹标记
            _visitedStack.Add(m.Member, newType);

            if (TypeUtils.IsPrimitive(m.Member))
            {
                this.VisitMemberBinding(m);
                // 选择字段
                this.AddSelectedColumn(m.Member, newType);
            }
            else
            {
                // 非显式指定的导航属性需要有 ForeignKeyAttribute
                if (m.Expression.NodeType == ExpressionType.MemberAccess && m.Expression.Visitable())
                {
                    var typeRuntime = TypeRuntimeInfoCache.GetRuntimeInfo(newType);
                    var attribute   = typeRuntime.GetMemberAttribute <ForeignKeyAttribute>(m.Member.Name);
                    // 不能当做导航属性的复杂字段
                    if (attribute == null)
                    {
                        return;
                    }
                }

                // 生成导航属性描述集合,以类名.属性名做为键值
                if (_navDescriptorKeys == null)
                {
                    _navDescriptorKeys = new List <string>();
                }
                if (_navDescriptors == null)
                {
                    _navDescriptors = new NavDescriptorCollection();
                }

                int    num   = _navDescriptorKeys.Count;
                string keyId = _navDescriptorKeys.Count > 0 ? _navDescriptorKeys[_navDescriptorKeys.Count - 1] : string.Empty;
                keyId = !string.IsNullOrEmpty(keyId) ? keyId + "." + m.Member.Name : m.Member.Name;

                var nav = new NavDescriptor(keyId, m.Member);
                if (!_navDescriptors.Contains(keyId))
                {
                    // Fix issue# spliton 列占一个位
                    nav.StartIndex = _selectedColumns.Count;
                    nav.FieldCount = GetFieldCount(m.Expression) + (m.Expression.NodeType == ExpressionType.MemberAccess && m.Expression.Visitable() ? 1 : 0);
                    _navDescriptors.Add(nav);
                    _navDescriptorKeys.Add(keyId);
                }

                // 1.不显式指定导航属性,例:a.Client.ClientList
                // 2.表达式里显式指定导航属性,例:b
                if (m.Expression.NodeType == ExpressionType.MemberAccess)
                {
                    this.VisitNavigation(m.Expression as MemberExpression, m.Expression.Visitable());
                }
                else if (m.Expression.NodeType == ExpressionType.New)
                {
                    this.VisitNewImpl(m.Expression as NewExpression, false);
                }
                else if (m.Expression.NodeType == ExpressionType.MemberInit)
                {
                    this.VisitMemberInit(m.Expression as MemberInitExpression);
                }

                // 恢复访问链
                // 在访问导航属性时可能是 Client.CloudServer,这时要恢复为 Client,以保证能访问 Client 的下一个导航属性
                if (_navDescriptorKeys.Count != num)
                {
                    _navDescriptorKeys.RemoveAt(_navDescriptorKeys.Count - 1);
                }
            }
        }
Пример #2
0
        /// <summary>
        /// 访问字段或者属性表达式
        /// </summary>
        /// <param name="node">字段或者成员表达式</param>
        /// <returns></returns>
        protected override Expression VisitMember(MemberExpression node)
        {
            // 1.<>h__TransparentIdentifier3.b.Client.ClientName
            // 2.<>h__TransparentIdentifier3.b.Client.ClientName.Length
            // 3.<>h__TransparentIdentifier3.b.Client.Address.AddressName
            // 4.<>h__TransparentIdentifier3.b.ClientName
            // <>h__TransparentIdentifier2.<>h__TransparentIdentifier3.b.ClientName
            // <>h__TransparentIdentifier2.<>h__TransparentIdentifier3.b.Client.ClientName
            // <>h__TransparentIdentifier2.<>h__TransparentIdentifier3.b.Client.Address.AddressName
            // 5.b.ClientName


            if (node == null)
            {
                return(node);
            }
            // => a.ActiveDate == DateTime.Now  => a.State == (byte)state
            if (node.CanEvaluate())
            {
                return(this.VisitConstant(node.Evaluate()));
            }
            // => DateTime.Now
            if (node.Type == typeof(DateTime) && node.Expression == null)
            {
                return(this.VisitMethodCall(node, MethodCallType.MemberMember));
            }
            // => a.Nullable.Value
            bool isNullable = node.Expression.Type.IsGenericType && node.Member.Name == "Value" && node.Expression.Type.GetGenericTypeDefinition() == typeof(Nullable <>);

            if (isNullable)
            {
                this.Visit(node.Expression);
                return(node);
            }

            // 记录访问成员栈
            _visitedStack.Add(node);

            // => a.Name.Length
            if (TypeUtils.IsPrimitiveType(node.Expression.Type))
            {
                return(this.VisitMethodCall(node, MethodCallType.MemberMember));
            }
            // => <>h__3.b.ClientName
            if (!node.Expression.Visitable())
            {
                _builder.AppendMember(_ag, node);
                return(node);
            }
            // => a.Accounts[0].Markets[0].MarketId
            // => b.Client.Address.AddressName
            Expression objExpression = node.Expression;
            bool       isMethodCall  = objExpression != null && objExpression.NodeType == ExpressionType.Call;

            if (isMethodCall)
            {
                MethodCallExpression methodExpression = objExpression as MethodCallExpression;
                bool isIndex = methodExpression.IsCollectionIndex();
                if (isIndex)
                {
                    objExpression = methodExpression.Object;
                }
            }
            // => b.Client.Address.AddressName
            this.VisitNavMember(objExpression, TypeUtils.GetFieldName(node.Member, node.Expression.Type));

            return(node);
        }
 // 访问对象成员
 private Expression VisitObjectMember(Type newType, MemberInfo member, Expression expression)
 {
     // 先添加当前字段的访问痕迹标记
     _visitedStack.Add(member, newType);
     return(base.Visit(expression));
 }