Skip to content

QueryableMethodNormalizingExpressionVisitor does not visit recursively when converting List.Contains to Queryable.Contains #32215

@roji

Description

@roji

Test PrimitiveCollectionsQuerySqlServerTest.Nested_contains_with_Lists_and_no_inferred_type_mapping) has a nested Contains case with array parameter parameters, where the inner contains gets translated via the old-style constant expansion rather than as a parameter query root (i.e. with OPENJSON):

[ConditionalTheory] // #32208
[MemberData(nameof(IsAsyncData))]
public virtual Task Nested_contains_with_Lists_and_no_inferred_type_mapping(bool async)
{
    var ints = new List<int> { 1, 2, 3 };
    var strings = new List<string> { "one", "two", "three" };

    // Note that in this query, the outer Contains really has no type mapping, neither for its source (collection parameter), nor
    // for its item (the conditional expression returns constants). The default type mapping must be applied.
    return AssertQuery(
        async,
        ss => ss.Set<PrimitiveCollectionsEntity>().Where(e => strings.Contains(ints.Contains(e.Int) ? "one" : "two")));
}

SQL:

SELECT [p].[Id], [p].[Bool], [p].[Bools], [p].[DateTime], [p].[DateTimes], [p].[Enum], [p].[Enums], [p].[Int], [p].[Ints], [p].[NullableInt], [p].[NullableInts], [p].[NullableString], [p].[NullableStrings], [p].[String], [p].[Strings]
FROM [PrimitiveCollectionsEntity] AS [p]
WHERE CASE
    WHEN [p].[Int] IN (1, 2, 3) THEN N'one'
    ELSE N'two'
END IN (
    SELECT [s].[value]
    FROM OPENJSON(@__strings_0) WITH ([value] nvarchar(max) '$') AS [s]
)

Metadata

Metadata

Assignees

Type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions