// 遍历 Include 包含的导航属性 private void VisitInclude() { if (_include == null || _include.Count == 0) { return; } foreach (var dbExpression in _include) { 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> chain = 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("Include member {{{0}}} must mark 'ForeignKeyAttribute'.", memberExpression); } MemberExpression m = null; chain.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) { chain.Add(memberExpression.Expression); } memberExpression = m; } // 生成导航属性描述信息 string keyId = string.Empty; for (int i = chain.Count - 1; i >= 0; i--) { Expression expression = chain[i]; memberExpression = expression as MemberExpression; if (memberExpression == null) { continue; } keyId = memberExpression.GetKeyWidthoutAnonymous(true); if (!_navDescriptors.Contains(keyId)) { // Fix issue# SplitOn 列占一个位 var nav = new NavDescriptor(keyId, memberExpression.Member); nav.StartIndex = i == 0 ? _pickColumns.Count : -1; nav.FieldCount = i == 0 ? (GetFieldCount(pickExpression == null ? navExpression : pickExpression) + 1) : -1; _navDescriptors.Add(nav); } } this.VisitNavigation(memberExpression, true, pickExpression, predicateExpression); } }
// => Name = "Name" private void VisitMemberAssignmentImpl(Type newType, MemberAssignment m) { // 先添加当前字段的访问痕迹标记 _visitedStack.Add(m.Member, newType); if (TypeUtils.IsPrimitive(m.Member)) { //if (ma.Expression.CanEvaluate()) // _builder.Append(ma.Expression.Evaluate().Value, ma.Member); //else // this.VisitWithoutRemark(x => this.VisitMemberBinding(ma)); this.VisitMemberBinding(m); // 选择字段 this.AddPickColumn(m.Member.Name); } 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) { throw new XFrameworkException("Complex property {{{0}}} must mark 'ForeignKeyAttribute' ", m.Member.Name); } } // 生成导航属性描述集合,以类名.属性名做为键值 int n = _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 = _pickColumns.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 != n) { _navDescriptorKeys.RemoveAt(_navDescriptorKeys.Count - 1); } } }