Skip to content

Commit 8499531

Browse files
committed
Fix to #35024 - Query could not be translated when using a static ICollection/IList field
Problem was that when converting primitive collection to inline query root we were not matching the expression if it was constant wrapped in convert. Fix is to remove convert for the purpose of pattern match for the transformation. Fixes #35024
1 parent 507e7f1 commit 8499531

File tree

5 files changed

+53
-1
lines changed

5 files changed

+53
-1
lines changed

src/EFCore/Query/QueryRootProcessor.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ protected override Expression VisitMethodCall(MethodCallExpression methodCallExp
8585

8686
private Expression VisitQueryRootCandidate(Expression expression, Type elementClrType)
8787
{
88-
switch (expression)
88+
switch (RemoveConvert(expression))
8989
{
9090
// An array containing only constants is represented as a ConstantExpression with the array as the value.
9191
// Convert that into a NewArrayExpression for use with InlineQueryRootExpression
@@ -122,6 +122,11 @@ when listInitExpression.Type.TryGetElementType(typeof(IList<>)) is not null
122122
default:
123123
return Visit(expression);
124124
}
125+
126+
static Expression RemoveConvert(Expression e)
127+
=> e is UnaryExpression { NodeType: ExpressionType.Convert or ExpressionType.ConvertChecked } unary
128+
? RemoveConvert(unary.Operand)
129+
: e;
125130
}
126131

127132
/// <summary>

test/EFCore.Cosmos.FunctionalTests/Query/NorthwindAggregateOperatorsQueryCosmosTest.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2068,6 +2068,20 @@ public override async Task Contains_with_local_anonymous_type_array_closure(bool
20682068
AssertSql();
20692069
}
20702070

2071+
public override Task Contains_with_static_IList(bool async)
2072+
=> Fixture.NoSyncTest(
2073+
async, async a =>
2074+
{
2075+
await base.Contains_with_static_IList(a);
2076+
2077+
AssertSql(
2078+
"""
2079+
SELECT VALUE c
2080+
FROM root c
2081+
WHERE c["id"] IN ("ALFKI", "ANATR")
2082+
""");
2083+
});
2084+
20712085
public override async Task OfType_Select(bool async)
20722086
{
20732087
// Contains over subquery. Issue #17246.

test/EFCore.Specification.Tests/Query/NorthwindAggregateOperatorsQueryTestBase.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1361,6 +1361,15 @@ public virtual Task Contains_with_local_anonymous_type_array_closure(bool async)
13611361
ss => ss.Set<OrderDetail>().Where(o => ids.Contains(new { Id1 = o.OrderID, Id2 = o.ProductID })));
13621362
}
13631363

1364+
private static readonly IList<string> StaticIds = new List<string> { "ALFKI", "ANATR" };
1365+
1366+
[ConditionalTheory]
1367+
[MemberData(nameof(IsAsyncData))]
1368+
public virtual Task Contains_with_static_IList(bool async)
1369+
=> AssertQuery(
1370+
async,
1371+
ss => ss.Set<Customer>().Where(c => StaticIds.Contains(c.CustomerID)));
1372+
13641373
[ConditionalTheory]
13651374
[MemberData(nameof(IsAsyncData))]
13661375
public virtual Task OfType_Select(bool async)

test/EFCore.SqlServer.FunctionalTests/Query/NorthwindAggregateOperatorsQuerySqlServerTest.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2303,6 +2303,18 @@ public override async Task Contains_with_local_anonymous_type_array_closure(bool
23032303
AssertSql();
23042304
}
23052305

2306+
public override async Task Contains_with_static_IList(bool async)
2307+
{
2308+
await base.Contains_with_static_IList(async);
2309+
2310+
AssertSql(
2311+
"""
2312+
SELECT [c].[CustomerID], [c].[Address], [c].[City], [c].[CompanyName], [c].[ContactName], [c].[ContactTitle], [c].[Country], [c].[Fax], [c].[Phone], [c].[PostalCode], [c].[Region]
2313+
FROM [Customers] AS [c]
2314+
WHERE [c].[CustomerID] IN (N'ALFKI', N'ANATR')
2315+
""");
2316+
}
2317+
23062318
public override async Task OfType_Select(bool async)
23072319
{
23082320
await base.OfType_Select(async);

test/EFCore.Sqlite.FunctionalTests/Query/NorthwindAggregateOperatorsQuerySqliteTest.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,18 @@ public override async Task Contains_with_local_anonymous_type_array_closure(bool
123123
public override async Task Contains_with_local_tuple_array_closure(bool async)
124124
=> await AssertTranslationFailed(() => base.Contains_with_local_tuple_array_closure(async));
125125

126+
public override async Task Contains_with_static_IList(bool async)
127+
{
128+
await base.Contains_with_static_IList(async);
129+
130+
AssertSql(
131+
"""
132+
SELECT "c"."CustomerID", "c"."Address", "c"."City", "c"."CompanyName", "c"."ContactName", "c"."ContactTitle", "c"."Country", "c"."Fax", "c"."Phone", "c"."PostalCode", "c"."Region"
133+
FROM "Customers" AS "c"
134+
WHERE "c"."CustomerID" IN ('ALFKI', 'ANATR')
135+
""");
136+
}
137+
126138
public override async Task Contains_inside_aggregate_function_with_GroupBy(bool async)
127139
{
128140
await base.Contains_inside_aggregate_function_with_GroupBy(async);

0 commit comments

Comments
 (0)