protected virtual Expression VisitExtendedMemberInit(ExtendedMemberInitExpression node) { var newExpression = VisitAndConvert(node.NewExpression, nameof(VisitExtendedMemberInit)); var arguments = Visit(node.Arguments).ToArray(); var entityType = model.FindEntityType(node.Type); if (entityType != null) { var collectionMembers = from n in entityType.GetNavigations() where n.IsCollection() from m in new[] { n.GetReadableMemberInfo(), n.GetWritableMemberInfo() } select m; for (var i = 0; i < arguments.Length; i++) { if (collectionMembers.Contains(node.WritableMembers[i])) { var sequenceType = node.WritableMembers[i].GetMemberType().GetSequenceType(); arguments[i] = Expression.Coalesce( arguments[i].AsCollectionType(), Expression.New(typeof(List <>).MakeGenericType(sequenceType))); } } } return(node.Update(newExpression, arguments)); }
private static bool FindExpressionForMember(ExtendedMemberInitExpression extendedMemberInitExpression, MemberInfo memberInfo, out Expression expression) { for (var i = 0; i < extendedMemberInitExpression.ReadableMembers.Count; i++) { var member = extendedMemberInitExpression.ReadableMembers[i]; if (member.DeclaringType == memberInfo.DeclaringType && member.Name == memberInfo.Name) { expression = extendedMemberInitExpression.Arguments[i]; return(true); } } return(FindExpressionForMember(extendedMemberInitExpression.NewExpression, memberInfo, out expression)); }
protected virtual Expression VisitExtendedMemberInit(ExtendedMemberInitExpression node) { var newExpression = VisitAndConvert(node.NewExpression, nameof(VisitExtendedMemberInit)); if (Finished) { return(node.Update(newExpression, node.Arguments)); } var arguments = node.Arguments.ToList(); var readableMembers = node.ReadableMembers.ToList(); var writableMembers = node.WritableMembers.ToList(); var currentMember = path.Pop(); var currentMemberInfo = currentMember.GetReadableMemberInfo(); var foundMember = false; for (var i = 0; i < arguments.Count; i++) { var argument = arguments[i]; if (node.ReadableMembers[i] == currentMemberInfo) { foundMember = true; if (path.Count == 0) { arguments[i] = includedExpression; Finished = true; } else { arguments[i] = Visit(argument); } break; } } path.Push(currentMember); if (!foundMember && currentMemberInfo.DeclaringType.IsAssignableFrom(node.Type)) { Finished = true; var writableMemberInfo = currentMember.GetWritableMemberInfo(); arguments.Add( writableMemberInfo.GetMemberType().IsCollectionType() ? includedExpression.AsCollectionType() : includedExpression); readableMembers.Add(currentMember.GetReadableMemberInfo()); writableMembers.Add(writableMemberInfo); return(new ExtendedMemberInitExpression( node.Type, node.NewExpression, arguments, readableMembers, writableMembers)); } else { return(node.Update(newExpression, arguments)); } }
private Expression CreateMaterializationExpression(IEntityType type, BaseTableExpression table, Func <IProperty, Expression> makeColumnExpression) { var properties = (from p in type.GetProperties() where !p.IsShadowProperty select p).ToList(); var navigations = (from n in type.GetNavigations() where n.ForeignKey.IsOwnership && !n.IsDependentToPrincipal() select n).ToList(); var services = (from s in type.GetServiceProperties() select s).ToList(); var newExpression = CreateNewExpression(type, table, makeColumnExpression); properties.RemoveAll(p => newExpression.WritableMembers.Contains(p.GetWritableMemberInfo())); navigations.RemoveAll(p => newExpression.WritableMembers.Contains(p.GetWritableMemberInfo())); services.RemoveAll(p => newExpression.WritableMembers.Contains(p.GetWritableMemberInfo())); var arguments = new Expression[properties.Count + navigations.Count + services.Count]; var readableMembers = new MemberInfo[arguments.Length]; var writableMembers = new MemberInfo[arguments.Length]; var c = properties.Count; var d = 0; for (var i = 0; i < c; i++) { var property = properties[i - d]; arguments[i] = makeColumnExpression(property); readableMembers[i] = property.GetReadableMemberInfo(); writableMembers[i] = property.GetWritableMemberInfo(); } c += navigations.Count; d += properties.Count; for (var i = d; i < c; i++) { var navigation = navigations[i - d]; arguments[i] = CreateMaterializationExpression(navigation.GetTargetType(), table, makeColumnExpression); readableMembers[i] = navigation.GetReadableMemberInfo(); writableMembers[i] = navigation.GetWritableMemberInfo(); } c += services.Count; d += navigations.Count; for (var i = d; i < c; i++) { var service = services[i - d]; arguments[i] = GetBindingExpression(type, service.GetParameterBinding(), makeColumnExpression); readableMembers[i] = service.GetReadableMemberInfo(); writableMembers[i] = service.GetWritableMemberInfo(); } var materializer = new ExtendedMemberInitExpression( type.ClrType, newExpression, arguments, readableMembers, writableMembers); var keySelector = CreateMaterializationKeySelector(type); if (keySelector != null) { var shadowProperties = from p in type.GetProperties() where p.IsShadowProperty select(property : p, expression : makeColumnExpression(p)); return(new EntityMaterializationExpression( type, IdentityMapMode.IdentityMap, keySelector, shadowProperties.Select(s => s.property), shadowProperties.Select(s => s.expression), materializer)); } return(materializer); }