diff --git a/src/EFCore.Design/Query/Internal/PrecompiledQueryCodeGenerator.cs b/src/EFCore.Design/Query/Internal/PrecompiledQueryCodeGenerator.cs index 954e7218fea..72b3614884f 100644 --- a/src/EFCore.Design/Query/Internal/PrecompiledQueryCodeGenerator.cs +++ b/src/EFCore.Design/Query/Internal/PrecompiledQueryCodeGenerator.cs @@ -1170,6 +1170,11 @@ private static NewArrayExpression ProcessExecuteUpdate(MethodCallExpression exec var settersParameter = settersLambda.Parameters.Single(); var expression = settersLambda.Body; + // Use a Stack to reverse the order of processing. + // The expression tree is nested (Last Call is the Outer-most node). + // We want to process them First -> Last. + var calls = new Stack(); + while (expression != settersParameter) { if (expression is MethodCallExpression @@ -1187,19 +1192,8 @@ private static NewArrayExpression ProcessExecuteUpdate(MethodCallExpression exec } methodCallExpression && methodCallExpression.Method.DeclaringType.GetGenericTypeDefinition() == typeof(UpdateSettersBuilder<>)) { - if (valueSelector is UnaryExpression - { - NodeType: ExpressionType.Quote, - Operand: LambdaExpression unwrappedValueSelector - }) - { - settersBuilder.SetProperty(propertySelector, unwrappedValueSelector); - } - else - { - settersBuilder.SetProperty(propertySelector, valueSelector); - } - + // Push to stack to process later + calls.Push(methodCallExpression); expression = methodCallExpression.Object; continue; } @@ -1207,6 +1201,27 @@ private static NewArrayExpression ProcessExecuteUpdate(MethodCallExpression exec throw new InvalidOperationException(RelationalStrings.InvalidArgumentToExecuteUpdate); } + // Process the stack (First-In, Last-Out) effectively reversing the tree traversal + // so setters are added in the order they were written in source code. + foreach (var methodCallExpression in calls) + { + var propertySelector = (LambdaExpression)((UnaryExpression)methodCallExpression.Arguments[0]).Operand; + var valueSelector = methodCallExpression.Arguments[1]; + + if (valueSelector is UnaryExpression + { + NodeType: ExpressionType.Quote, + Operand: LambdaExpression unwrappedValueSelector + }) + { + settersBuilder.SetProperty(propertySelector, unwrappedValueSelector); + } + else + { + settersBuilder.SetProperty(propertySelector, valueSelector); + } + } + return settersBuilder.BuildSettersExpression(); }