protected override Expression VisitMemberInit(MemberInitExpression memberInitExpression) { var visitedNew = Visit(memberInitExpression.NewExpression); var(visitedBindings, entityReferenceInfo) = VisitMemberBindings(memberInitExpression.Bindings); var visitedMemberInit = memberInitExpression.Update((NewExpression)Unwrap(visitedNew), visitedBindings); return(entityReferenceInfo == null ? (Expression)visitedMemberInit : new EntityReferenceExpression(visitedMemberInit, entityReferenceInfo)); // Visits member bindings, unwrapping expressions and surfacing entity reference information via the dictionary (IEnumerable <MemberBinding>, Dictionary <string, EntityOrDtoType>) VisitMemberBindings(ReadOnlyCollection <MemberBinding> bindings) { var newBindings = new MemberBinding[bindings.Count]; Dictionary <string, EntityOrDtoType> bindingEntityReferenceInfo = null; for (var i = 0; i < bindings.Count; i++) { switch (bindings[i]) { case MemberAssignment assignment: var visitedAssignment = VisitMemberAssignment(assignment); if (visitedAssignment.Expression is EntityReferenceExpression ere) { if (bindingEntityReferenceInfo == null) { bindingEntityReferenceInfo = new Dictionary <string, EntityOrDtoType>(); } bindingEntityReferenceInfo[assignment.Member.Name] = EntityOrDtoType.FromEntityReferenceExpression(ere); } newBindings[i] = assignment.Update(Unwrap(visitedAssignment.Expression)); continue; default: newBindings[i] = VisitMemberBinding(bindings[i]); continue; } } return(newBindings, bindingEntityReferenceInfo); } }
protected override Expression VisitNew(NewExpression newExpression) { var visitedArgs = Visit(newExpression.Arguments); var visitedExpression = newExpression.Update(visitedArgs.Select(Unwrap)); // NewExpression.Members is populated for anonymous types, mapping constructor arguments to the properties // which receive their values. If not populated, a non-anonymous type is being constructed, and we have no idea where // its constructor arguments will end up. if (newExpression.Members == null) { return(visitedExpression); } var entityReferenceInfo = visitedArgs .Select((a, i) => (Arg: a, Index: i)) .Where(ai => ai.Arg is EntityReferenceExpression) .ToDictionary( ai => visitedExpression.Members[ai.Index].Name, ai => EntityOrDtoType.FromEntityReferenceExpression((EntityReferenceExpression)ai.Arg)); return(entityReferenceInfo.Count == 0 ? (Expression)visitedExpression : new EntityReferenceExpression(visitedExpression, entityReferenceInfo)); }