// => 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); } } }
/// <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)); }