Example #1
0
        // 遍历 Include 包含的导航属性
        private void VisitInclude()
        {
            if (_includes == null || _includes.Count == 0)
            {
                return;
            }

            foreach (var dbExpression in _includes)
            {
                Expression navExpression       = dbExpression.Expressions[0];
                Expression pickExpression      = dbExpression.Expressions.Length > 1 ? dbExpression.Expressions[1] : null;
                Expression predicateExpression = dbExpression.Expressions.Length > 2 ? dbExpression.Expressions[2] : null;
                if (navExpression == null)
                {
                    continue;
                }

                if (navExpression.NodeType == ExpressionType.Lambda)
                {
                    navExpression = (navExpression as LambdaExpression).Body;
                }
                var memberExpression = navExpression as MemberExpression;
                if (memberExpression == null)
                {
                    throw new XFrameworkException("Include expression body must be 'MemberExpression'.");
                }

                // 例:Include(a => a.Client.AccountList[0].Client)
                // 解析导航属性链
                List <Expression> navStack = new List <Expression>();
                while (memberExpression != null)
                {
                    // a.Client 要求 <Client> 必须标明 ForeignKeyAttribute
                    var typeRuntime = TypeRuntimeInfoCache.GetRuntimeInfo(memberExpression.Expression.Type);
                    var attribute   = typeRuntime.GetMemberAttribute <ForeignKeyAttribute>(memberExpression.Member.Name);
                    if (attribute == null)
                    {
                        throw new XFrameworkException("ForeignKeyAttribute not found for include member {0}.{1}", typeRuntime.Type.Name, memberExpression.Member.Name);
                    }

                    MemberExpression m = null;
                    navStack.Add(memberExpression);
                    if (memberExpression.Expression.NodeType == ExpressionType.MemberAccess)
                    {
                        m = (MemberExpression)memberExpression.Expression;
                    }
                    else if (memberExpression.Expression.NodeType == ExpressionType.Call)
                    {
                        m = (memberExpression.Expression as MethodCallExpression).Object as MemberExpression;
                    }

                    //var m = memberExpression.Expression as MemberExpression;
                    if (m == null)
                    {
                        navStack.Add(memberExpression.Expression);
                    }
                    memberExpression = m;
                }

                // 生成导航属性描述信息
                string keyId = string.Empty;
                for (int index = navStack.Count - 1; index >= 0; index--)
                {
                    Expression expression = navStack[index];
                    memberExpression = expression as MemberExpression;
                    if (memberExpression == null)
                    {
                        continue;
                    }

                    if (_navDescriptors == null)
                    {
                        _navDescriptors = new NavDescriptorCollection();
                    }
                    keyId = memberExpression.GetKeyWidthoutAnonymous(true);
                    if (!_navDescriptors.Contains(keyId))
                    {
                        // Fix issue# SplitOn 列占一个位
                        var nav = new NavDescriptor(keyId, memberExpression.Member);
                        nav.StartIndex = index == 0 ? _selectedColumns.Count : -1;
                        nav.FieldCount = index == 0 ? (GetFieldCount(pickExpression == null ? navExpression : pickExpression) + 1) : -1;
                        _navDescriptors.Add(nav);
                    }
                }

                this.VisitNavigation(memberExpression, true, pickExpression, predicateExpression);
            }
        }
Example #2
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);
                }
            }
        }