Conversation
…EvaluatableRoot Co-authored-by: roji <1862641+roji@users.noreply.github.com> Agent-Logs-Url: https://github.com/dotnet/efcore/sessions/1452f6d8-60ff-43d5-9380-319e917be42b
Copilot
AI
changed the title
[WIP] Fix SetProperty lambda issue for nullable int properties
Fix SetProperty discard lambda failing for nullable value type properties in ExecuteUpdate
Mar 23, 2026
roji
approved these changes
Mar 23, 2026
There was a problem hiding this comment.
Pull request overview
Fixes a regression in EF Core 10+ where ExecuteUpdate/SetProperty with a discard lambda (e.g. _ => 1) fails for nullable value type properties (e.g. int?) due to ExpressionTreeFuncletizer state being inadvertently re-marked as evaluatable during constantization.
Changes:
- Reset funcletizer state back to
NoEvaluatabilityafterConvertIfNeeded(...)in the constant-evaluation path to prevent state corruption. - Add a specification test covering
int?property assignment via discard lambda inExecuteUpdate. - Add SQL baselines for the new test in SQLite and SQL Server functional tests.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| src/EFCore/Query/Internal/ExpressionTreeFuncletizer.cs | Resets state after ConvertIfNeeded to avoid incorrectly treating a discard setter lambda as evaluatable. |
| test/EFCore.Specification.Tests/BulkUpdates/NorthwindBulkUpdatesTestBase.cs | Adds spec test for setting Product.SupplierID (int?) via _ => 1 in ExecuteUpdate. |
| test/EFCore.Sqlite.FunctionalTests/BulkUpdates/NorthwindBulkUpdatesSqliteTest.cs | Adds SQLite SQL baseline for the new nullable int discard-lambda update test. |
| test/EFCore.SqlServer.FunctionalTests/BulkUpdates/NorthwindBulkUpdatesSqlServerTest.cs | Adds SQL Server SQL baseline for the new nullable int discard-lambda update test. |
AndriySvyryd
approved these changes
Mar 24, 2026
roji
added a commit
to roji/efcore
that referenced
this pull request
Mar 26, 2026
…ties in ExecuteUpdate Backport of dotnet#37975 to release/10.0. In ExpressionTreeFuncletizer.ProcessEvaluatableRoot, ConvertIfNeeded calls Visit which corrupts _state back to EvaluatableWithoutCapturedVariable when wrapping a constant int to int?. This causes the parent VisitLambda to treat the lambda as evaluatable, compiling it to a Func and breaking TranslateSetterValueSelector. Fix: reset state to NoEvaluatability after ConvertIfNeeded returns. Added quirk Microsoft.EntityFrameworkCore.Issue37974 to opt out. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
In EF Core 10+,
SetProperty(p => p.NullableIntProp, _ => 1)throwsInvalidOperationException: No coercion operator is defined between types 'Func<Entity, int?>' and 'int'. Non-nullable and reference types are unaffected.Root cause
ExpressionTreeFuncletizer.ProcessEvaluatableRoot, when constantizing a node, setsstate = NoEvaluatabilitythen callsConvertIfNeeded(Constant(1, int), int?)to wrap the result.ConvertIfNeededcallsVisit(Convert(Constant(1, int), int?))— which resets and re-computes_stateasEvaluatableWithoutCapturedVariable, since theConvertnode is itself evaluatable.Because
stateisref _state, this corrupts the state back inVisitLambda: the lambda_ => 1incorrectly appears evaluatable, so its parent (VisitNewfor the setterNewExpression) compiles the whole lambda to aFunc<Entity, int?>and emits aQueryParameterExpression<Func<Entity, int?>>.TranslateSetterValueSelectorthen receives this parameter expression instead of aLambdaExpressionand throws.Fix
ExpressionTreeFuncletizer.ProcessEvaluatableRoot: AfterConvertIfNeededreturns in the constant-evaluation path, reassignstate = State.NoEvaluatabilityto undo the corruption introduced byConvertIfNeeded's internalVisitcall.Test
Update_Where_set_nullable_int_constant_via_discard_lambdatoNorthwindBulkUpdatesTestBaseusingProduct.SupplierID(int?) with_ => 1, with SQL baseline assertions in the SQLite and SQL Server test classes.Original prompt
This section details on the original issue you should resolve
<issue_title>Breaking change in EF Core 10: SetProperty lambda with discarded parameter (_ =>) fails with "No coercion operator defined" for nullable int properties in ExecuteUpdateAsync</issue_title>
<issue_description>
After upgrading from EF Core 9 to EF Core 10,
ExecuteUpdateAsyncthrows aSystem.InvalidOperationExceptionwhen usingSetPropertyto assign a constant or captured value to a nullable property (int?).I'm aware of the [breaking change in EF Core 10](https://learn.microsoft.com/en-us/ef/core/what-is-new/ef-core-10.0/breaking-changes#execute-update-expression) where the column setters parameter moved from
Expression<Func<...>>toFunc<...>. However, the nullable value-type coercion failure seems like it may be an unintended side effect of that change rather than expected behavior.Exception
Reproduce
Entity
Failing code (worked in EF Core 9)
The same pattern with non-nullable properties or
stringproperties does not fail.Workaround 1 — use entity parameter instead of discard
Workaround 2 — capture as a pre-typed variable
Expected behavior
Assigning a constant
intvalue to anint?property viaSetPropertyshould work regardless of whether the lambda uses a discard (_ =>) or an entity parameter (p =>). The implicitint→int?coercion should be handled transparently, as it was in EF Core 9.Actual behavior
EF Core 10 throws
InvalidOperationExceptionat query compilation time. The error originates inTryTranslateSetterValueSelector, suggesting the newFunc-based setter pipeline does not handle theint→Nullable<int>coercion when the lambda uses a discarded parameter.Notably:
_ =>top =>resolves the issue, even though the parameter is unused.int?outside the lambda also resolves it.string) are unaffected.This suggests the regression is specific to how the discard-parameter lambda's return type is inferred for nullable value types under the new
Func-based API.Stack trace
Question
Is the nullable coercion failure with
_ =>an intended consequence of theExpression<Func<...>>→Func<...>migration, or is this a regression that should be handled by the new setter translation pipeline?Provider and version information
Comments on the Issue (you are @copilot in this section)
@roji # AI TriageThe below is an AI-generated analysis and may contain inaccuracies.
Classification
Bug — confirmed regression from EF Core 9 to EF Core 10. The bug also exists on the current
mainbranch (11.0 development).Root cause
The bug is in `...
⚡ Quickly spin up Copilot coding agent tasks from anywhere on your macOS or Windows machine with Raycast.