Skip to content

Commit c4cbb7e

Browse files
Copilotroji
andcommitted
Fix nullable value type coercion in ExpressionTreeFuncletizer.ProcessEvaluatableRoot
Co-authored-by: roji <1862641+roji@users.noreply.github.com> Agent-Logs-Url: https://github.com/dotnet/efcore/sessions/1452f6d8-60ff-43d5-9380-319e917be42b
1 parent 2d262ca commit c4cbb7e

4 files changed

Lines changed: 41 additions & 1 deletion

File tree

src/EFCore/Query/Internal/ExpressionTreeFuncletizer.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2006,10 +2006,15 @@ private static StateType CombineStateTypes(StateType stateType1, StateType state
20062006
return evaluatableRoot;
20072007
}
20082008

2009-
return ConvertIfNeeded(
2009+
var constantExpression = ConvertIfNeeded(
20102010
Constant(value, value is null ? evaluatableRoot.Type : value.GetType()),
20112011
evaluatableRoot.Type);
20122012

2013+
// ConvertIfNeeded calls Visit which may have modified _state; reset it since we've already evaluated this root as a constant.
2014+
state = State.NoEvaluatability;
2015+
2016+
return constantExpression;
2017+
20132018
bool TryHandleNonEvaluatableAsRoot(Expression root, State state, bool asParameter, [NotNullWhen(true)] out Expression? result)
20142019
{
20152020
switch (root)

test/EFCore.Specification.Tests/BulkUpdates/NorthwindBulkUpdatesTestBase.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -392,6 +392,16 @@ public virtual Task Update_Where_set_constant_via_lambda(bool async)
392392
rowsAffectedCount: 8,
393393
(b, a) => Assert.All(a, c => Assert.Equal("Updated", c.ContactName)));
394394

395+
[ConditionalTheory, MemberData(nameof(IsAsyncData))]
396+
public virtual Task Update_Where_set_nullable_int_constant_via_discard_lambda(bool async)
397+
=> AssertUpdate(
398+
async,
399+
ss => ss.Set<Product>().Where(p => p.ProductID < 5),
400+
e => e,
401+
s => s.SetProperty(c => c.SupplierID, _ => 1),
402+
rowsAffectedCount: 4,
403+
(b, a) => Assert.All(a, p => Assert.Equal(1, p.SupplierID)));
404+
395405
[ConditionalTheory, MemberData(nameof(IsAsyncData))]
396406
public virtual async Task Update_Where_parameter_set_constant(bool async)
397407
{

test/EFCore.SqlServer.FunctionalTests/BulkUpdates/NorthwindBulkUpdatesSqlServerTest.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -688,6 +688,19 @@ WHERE [c].[CustomerID] LIKE N'F%'
688688
""");
689689
}
690690

691+
public override async Task Update_Where_set_nullable_int_constant_via_discard_lambda(bool async)
692+
{
693+
await base.Update_Where_set_nullable_int_constant_via_discard_lambda(async);
694+
695+
AssertExecuteUpdateSql(
696+
"""
697+
UPDATE [p]
698+
SET [p].[SupplierID] = 1
699+
FROM [Products] AS [p]
700+
WHERE [p].[ProductID] < 5
701+
""");
702+
}
703+
691704
public override async Task Update_Where_parameter_set_constant(bool async)
692705
{
693706
await base.Update_Where_parameter_set_constant(async);

test/EFCore.Sqlite.FunctionalTests/BulkUpdates/NorthwindBulkUpdatesSqliteTest.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -667,6 +667,18 @@ public override async Task Update_Where_set_constant_via_lambda(bool async)
667667
""");
668668
}
669669

670+
public override async Task Update_Where_set_nullable_int_constant_via_discard_lambda(bool async)
671+
{
672+
await base.Update_Where_set_nullable_int_constant_via_discard_lambda(async);
673+
674+
AssertExecuteUpdateSql(
675+
"""
676+
UPDATE "Products" AS "p"
677+
SET "SupplierID" = 1
678+
WHERE "p"."ProductID" < 5
679+
""");
680+
}
681+
670682
public override async Task Update_Where_parameter_set_constant(bool async)
671683
{
672684
await base.Update_Where_parameter_set_constant(async);

0 commit comments

Comments
 (0)