Skip to content

Commit

Permalink
Fix to #35024 - Query could not be translated when using a static ICo…
Browse files Browse the repository at this point in the history
…llection/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
  • Loading branch information
maumar committed Nov 1, 2024
1 parent 507e7f1 commit 8499531
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 1 deletion.
7 changes: 6 additions & 1 deletion src/EFCore/Query/QueryRootProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ protected override Expression VisitMethodCall(MethodCallExpression methodCallExp

private Expression VisitQueryRootCandidate(Expression expression, Type elementClrType)
{
switch (expression)
switch (RemoveConvert(expression))
{
// An array containing only constants is represented as a ConstantExpression with the array as the value.
// Convert that into a NewArrayExpression for use with InlineQueryRootExpression
Expand Down Expand Up @@ -122,6 +122,11 @@ when listInitExpression.Type.TryGetElementType(typeof(IList<>)) is not null
default:
return Visit(expression);
}

static Expression RemoveConvert(Expression e)
=> e is UnaryExpression { NodeType: ExpressionType.Convert or ExpressionType.ConvertChecked } unary
? RemoveConvert(unary.Operand)
: e;
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2068,6 +2068,20 @@ public override async Task Contains_with_local_anonymous_type_array_closure(bool
AssertSql();
}

public override Task Contains_with_static_IList(bool async)
=> Fixture.NoSyncTest(
async, async a =>
{
await base.Contains_with_static_IList(a);
AssertSql(
"""
SELECT VALUE c
FROM root c
WHERE c["id"] IN ("ALFKI", "ANATR")
""");
});

public override async Task OfType_Select(bool async)
{
// Contains over subquery. Issue #17246.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1361,6 +1361,15 @@ public virtual Task Contains_with_local_anonymous_type_array_closure(bool async)
ss => ss.Set<OrderDetail>().Where(o => ids.Contains(new { Id1 = o.OrderID, Id2 = o.ProductID })));
}

private static readonly IList<string> StaticIds = new List<string> { "ALFKI", "ANATR" };

[ConditionalTheory]
[MemberData(nameof(IsAsyncData))]
public virtual Task Contains_with_static_IList(bool async)
=> AssertQuery(
async,
ss => ss.Set<Customer>().Where(c => StaticIds.Contains(c.CustomerID)));

[ConditionalTheory]
[MemberData(nameof(IsAsyncData))]
public virtual Task OfType_Select(bool async)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2303,6 +2303,18 @@ public override async Task Contains_with_local_anonymous_type_array_closure(bool
AssertSql();
}

public override async Task Contains_with_static_IList(bool async)
{
await base.Contains_with_static_IList(async);

AssertSql(
"""
SELECT [c].[CustomerID], [c].[Address], [c].[City], [c].[CompanyName], [c].[ContactName], [c].[ContactTitle], [c].[Country], [c].[Fax], [c].[Phone], [c].[PostalCode], [c].[Region]
FROM [Customers] AS [c]
WHERE [c].[CustomerID] IN (N'ALFKI', N'ANATR')
""");
}

public override async Task OfType_Select(bool async)
{
await base.OfType_Select(async);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,18 @@ public override async Task Contains_with_local_anonymous_type_array_closure(bool
public override async Task Contains_with_local_tuple_array_closure(bool async)
=> await AssertTranslationFailed(() => base.Contains_with_local_tuple_array_closure(async));

public override async Task Contains_with_static_IList(bool async)
{
await base.Contains_with_static_IList(async);

AssertSql(
"""
SELECT "c"."CustomerID", "c"."Address", "c"."City", "c"."CompanyName", "c"."ContactName", "c"."ContactTitle", "c"."Country", "c"."Fax", "c"."Phone", "c"."PostalCode", "c"."Region"
FROM "Customers" AS "c"
WHERE "c"."CustomerID" IN ('ALFKI', 'ANATR')
""");
}

public override async Task Contains_inside_aggregate_function_with_GroupBy(bool async)
{
await base.Contains_inside_aggregate_function_with_GroupBy(async);
Expand Down

0 comments on commit 8499531

Please sign in to comment.