Fix NotSupportedException when parsing nested object initialization#979
Fix NotSupportedException when parsing nested object initialization#979
Conversation
Agent-Logs-Url: https://github.com/zzzprojects/System.Linq.Dynamic.Core/sessions/4683789c-0227-43d7-9432-4863adea1d4c Co-authored-by: StefH <249938+StefH@users.noreply.github.com>
| return Expression.MemberInit(Expression.New(type), memberBindings); | ||
| } | ||
|
|
||
| private static Expression? TryRebuildMemberInitExpression(MemberInitExpression memberInitExpression, Type targetType) |
There was a problem hiding this comment.
rewrite this method to:
private static bool TryRebuildMemberInitExpression(MemberInitExpression memberInitExpression, Type targetType, [NotNullWhen(true)] out Expression? expression)
There was a problem hiding this comment.
Done in 417258d. Rewrote the method signature to private static bool TryRebuildMemberInitExpression(MemberInitExpression memberInitExpression, Type targetType, [NotNullWhen(true)] out Expression? expression) and updated the call site accordingly.
Agent-Logs-Url: https://github.com/zzzprojects/System.Linq.Dynamic.Core/sessions/537f61ea-9dbe-4ae4-9fa8-0358f826f195 Co-authored-by: StefH <249938+StefH@users.noreply.github.com>
|
|
||
| // https://github.com/zzzprojects/System.Linq.Dynamic.Core/issues/701 | ||
| [Fact] | ||
| public void DynamicExpressionParser_ParseLambda_NestedObjectInitialization() |
There was a problem hiding this comment.
Add a unit test which goes 1 level deeper so that the code
if (bindingExpression is MemberInitExpression nestedMemberInit && bindingExpression.Type != targetMemberType)
{
if (!TryRebuildMemberInitExpression(nestedMemberInit, targetMemberType, out var rebuiltNested))
{
return false;
}
bindingExpression = rebuiltNested;
}
else if (bindingExpression.Type != targetMemberType)
{
bindingExpression = Expression.Convert(bindingExpression, targetMemberType);
}
is also tested
There was a problem hiding this comment.
Added in ddb00b9. The new test DynamicExpressionParser_ParseLambda_NestedObjectInitialization_ThreeLevelsDeep uses expression new (new (new (3 as Id) as Sub) as Sub) with models that have a shared Sub property name at each level (CustomerForNestedNewTest.Sub → DepartmentForNestedNewTest, DepartmentForNestedNewTest.Sub → SubDepartmentForNestedNewTest). This causes the outer rebuild to encounter an inner MemberInitExpression binding, triggering the recursive call path.
…MemberInitExpression Agent-Logs-Url: https://github.com/zzzprojects/System.Linq.Dynamic.Core/sessions/42b1ec4e-90f4-484b-ae3a-73f3bee9c50b Co-authored-by: StefH <249938+StefH@users.noreply.github.com>
Parsing expressions with nested
newinitializers likenew (new (3 as Id) as CurrentDepartment)throws aNotSupportedExceptionwhen the result type is a known class (e.g.Customer).Root cause: The parser propagates
_resultTypeinto nestednewexpressions that have no explicit type. Sonew (3 as Id)becomesnew Customer() {Id=3}. When the outer expression then tries to bind this toCurrentDepartment(typeDepartment),ExpressionPromoter.PromotereturnsnullandExpression.Convertthrows sinceCustomerandDepartmentare incompatible.Fix: In
CreateNewExpression's member-bindings path, whenPromotereturnsnulland the source expression is aMemberInitExpression, attempt to rebuild it for the target member type via a newTryRebuildMemberInitExpressionhelper. The helper:MemberInitExpressionvaluesnull(falls back toExpression.Convert) if any member is absent on the targetExample — previously threw, now works:
📱 Kick off Copilot coding agent tasks wherever you are with GitHub Mobile, available on iOS and Android.