From 14e6557d6f6597ba34cf43a65721366ff7897e2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jiri=20Cincura=20=E2=86=B9?= Date: Mon, 2 Dec 2024 15:18:45 +0100 Subject: [PATCH 1/3] Fix Contains on ImmutableArray (#35247) --- ...yableMethodNormalizingExpressionVisitor.cs | 6 +++- src/EFCore/Query/QueryRootProcessor.cs | 13 ++++++++- .../PrimitiveCollectionsQueryCosmosTest.cs | 24 ++++++++++++++++ .../PrimitiveCollectionsQueryTestBase.cs | 16 +++++++++++ ...imitiveCollectionsQueryOldSqlServerTest.cs | 18 ++++++++++++ ...imitiveCollectionsQuerySqlServer160Test.cs | 28 +++++++++++++++++++ ...veCollectionsQuerySqlServerJsonTypeTest.cs | 28 +++++++++++++++++++ .../PrimitiveCollectionsQuerySqlServerTest.cs | 28 +++++++++++++++++++ .../PrimitiveCollectionsQuerySqliteTest.cs | 28 +++++++++++++++++++ 9 files changed, 187 insertions(+), 2 deletions(-) diff --git a/src/EFCore/Query/Internal/QueryableMethodNormalizingExpressionVisitor.cs b/src/EFCore/Query/Internal/QueryableMethodNormalizingExpressionVisitor.cs index ad9d12fc3ae..f5c1db2329e 100644 --- a/src/EFCore/Query/Internal/QueryableMethodNormalizingExpressionVisitor.cs +++ b/src/EFCore/Query/Internal/QueryableMethodNormalizingExpressionVisitor.cs @@ -489,12 +489,16 @@ private Expression TryConvertCollectionContainsToQueryableContains(MethodCallExp var sourceType = methodCallExpression.Method.DeclaringType!.GetGenericArguments()[0]; + var objectExpression = methodCallExpression.Object!.Type.IsValueType + ? Expression.Convert(methodCallExpression.Object!, typeof(IEnumerable<>).MakeGenericType(sourceType)) + : methodCallExpression.Object!; + return VisitMethodCall( Expression.Call( QueryableMethods.Contains.MakeGenericMethod(sourceType), Expression.Call( QueryableMethods.AsQueryable.MakeGenericMethod(sourceType), - methodCallExpression.Object!), + objectExpression), methodCallExpression.Arguments[0])); } diff --git a/src/EFCore/Query/QueryRootProcessor.cs b/src/EFCore/Query/QueryRootProcessor.cs index ec87a57f35d..af0dc5b5e1f 100644 --- a/src/EFCore/Query/QueryRootProcessor.cs +++ b/src/EFCore/Query/QueryRootProcessor.cs @@ -85,7 +85,18 @@ protected override Expression VisitMethodCall(MethodCallExpression methodCallExp private Expression VisitQueryRootCandidate(Expression expression, Type elementClrType) { - switch (expression) + var candidateExpression = expression; + + // In case the collection was value type, in order to call methods like AsQueryable, + // we need to convert it to IEnumerable which requires boxing. + // We do that with Convert expression which we need to unwrap here. + if (expression is UnaryExpression { NodeType: ExpressionType.Convert } convertExpression + && convertExpression.Type.GetGenericTypeDefinition() == typeof(IEnumerable<>)) + { + candidateExpression = convertExpression.Operand; + } + + switch (candidateExpression) { // 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 diff --git a/test/EFCore.Cosmos.FunctionalTests/Query/PrimitiveCollectionsQueryCosmosTest.cs b/test/EFCore.Cosmos.FunctionalTests/Query/PrimitiveCollectionsQueryCosmosTest.cs index 78dd12d771c..f6bde5ef400 100644 --- a/test/EFCore.Cosmos.FunctionalTests/Query/PrimitiveCollectionsQueryCosmosTest.cs +++ b/test/EFCore.Cosmos.FunctionalTests/Query/PrimitiveCollectionsQueryCosmosTest.cs @@ -616,6 +616,30 @@ WHERE ARRAY_CONTAINS(@__ints_0, c["Int"]) SELECT VALUE c FROM root c WHERE NOT(ARRAY_CONTAINS(@__ints_0, c["Int"])) +"""); + }); + + public override Task Parameter_collection_ImmutableArray_of_ints_Contains_int(bool async) + => CosmosTestHelpers.Instance.NoSyncTest( + async, async a => + { + await base.Parameter_collection_ImmutableArray_of_ints_Contains_int(a); + + AssertSql( + """ +@ints='[10,999]' + +SELECT VALUE c +FROM root c +WHERE ARRAY_CONTAINS(@ints, c["Int"]) +""", + // + """ +@ints='[10,999]' + +SELECT VALUE c +FROM root c +WHERE NOT(ARRAY_CONTAINS(@ints, c["Int"])) """); }); diff --git a/test/EFCore.Specification.Tests/Query/PrimitiveCollectionsQueryTestBase.cs b/test/EFCore.Specification.Tests/Query/PrimitiveCollectionsQueryTestBase.cs index 2304ac3db4c..60e7cd24697 100644 --- a/test/EFCore.Specification.Tests/Query/PrimitiveCollectionsQueryTestBase.cs +++ b/test/EFCore.Specification.Tests/Query/PrimitiveCollectionsQueryTestBase.cs @@ -1,6 +1,8 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Collections.Immutable; + namespace Microsoft.EntityFrameworkCore.Query; public abstract class PrimitiveCollectionsQueryTestBase(TFixture fixture) : QueryTestBase(fixture) @@ -363,6 +365,20 @@ await AssertQuery( ss => ss.Set().Where(c => !ints.Contains(c.Int))); } + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual async Task Parameter_collection_ImmutableArray_of_ints_Contains_int(bool async) + { + var ints = ImmutableArray.Create([10, 999]); + + await AssertQuery( + async, + ss => ss.Set().Where(c => ints.Contains(c.Int))); + await AssertQuery( + async, + ss => ss.Set().Where(c => !ints.Contains(c.Int))); + } + [ConditionalTheory] [MemberData(nameof(IsAsyncData))] public virtual async Task Parameter_collection_of_ints_Contains_nullable_int(bool async) diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQueryOldSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQueryOldSqlServerTest.cs index d23ea73a1ce..fd1b12ba4f8 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQueryOldSqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQueryOldSqlServerTest.cs @@ -498,6 +498,24 @@ WHERE [p].[Int] NOT IN (10, 999) """); } + public override async Task Parameter_collection_ImmutableArray_of_ints_Contains_int(bool async) + { + await base.Parameter_collection_ImmutableArray_of_ints_Contains_int(async); + + AssertSql( + """ +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].[NullableWrappedId], [p].[NullableWrappedIdWithNullableComparer], [p].[String], [p].[Strings], [p].[WrappedId] +FROM [PrimitiveCollectionsEntity] AS [p] +WHERE [p].[Int] IN (10, 999) +""", + // + """ +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].[NullableWrappedId], [p].[NullableWrappedIdWithNullableComparer], [p].[String], [p].[Strings], [p].[WrappedId] +FROM [PrimitiveCollectionsEntity] AS [p] +WHERE [p].[Int] NOT IN (10, 999) +"""); + } + public override async Task Parameter_collection_of_ints_Contains_nullable_int(bool async) { await base.Parameter_collection_of_ints_Contains_nullable_int(async); diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServer160Test.cs b/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServer160Test.cs index a42b4ac42f7..220713d1bc4 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServer160Test.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServer160Test.cs @@ -525,6 +525,34 @@ FROM OPENJSON(@__ints_0) WITH ([value] int '$') AS [i] """); } + public override async Task Parameter_collection_ImmutableArray_of_ints_Contains_int(bool async) + { + await base.Parameter_collection_ImmutableArray_of_ints_Contains_int(async); + + AssertSql( + """ +@ints='[10,999]' (Nullable = false) (Size = 4000) + +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].[NullableWrappedId], [p].[NullableWrappedIdWithNullableComparer], [p].[String], [p].[Strings], [p].[WrappedId] +FROM [PrimitiveCollectionsEntity] AS [p] +WHERE [p].[Int] IN ( + SELECT [i].[value] + FROM OPENJSON(@ints) WITH ([value] int '$') AS [i] +) +""", + // + """ +@ints='[10,999]' (Nullable = false) (Size = 4000) + +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].[NullableWrappedId], [p].[NullableWrappedIdWithNullableComparer], [p].[String], [p].[Strings], [p].[WrappedId] +FROM [PrimitiveCollectionsEntity] AS [p] +WHERE [p].[Int] NOT IN ( + SELECT [i].[value] + FROM OPENJSON(@ints) WITH ([value] int '$') AS [i] +) +"""); + } + public override async Task Parameter_collection_of_ints_Contains_nullable_int(bool async) { await base.Parameter_collection_of_ints_Contains_nullable_int(async); diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServerJsonTypeTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServerJsonTypeTest.cs index d382ca0642d..ee5010eeaf2 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServerJsonTypeTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServerJsonTypeTest.cs @@ -541,6 +541,34 @@ FROM OPENJSON(@__ints_0) WITH ([value] int '$') AS [i] """); } + public override async Task Parameter_collection_ImmutableArray_of_ints_Contains_int(bool async) + { + await base.Parameter_collection_ImmutableArray_of_ints_Contains_int(async); + + AssertSql( + """ +@ints='[10,999]' (Nullable = false) (Size = 4000) + +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 [p].[Int] IN ( + SELECT [i].[value] + FROM OPENJSON(@ints) WITH ([value] int '$') AS [i] +) +""", + // + """ +@ints='[10,999]' (Nullable = false) (Size = 4000) + +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 [p].[Int] NOT IN ( + SELECT [i].[value] + FROM OPENJSON(@ints) WITH ([value] int '$') AS [i] +) +"""); + } + public override async Task Parameter_collection_of_ints_Contains_nullable_int(bool async) { await base.Parameter_collection_of_ints_Contains_nullable_int(async); diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServerTest.cs index de05c4c3797..6c15c9e3668 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServerTest.cs @@ -548,6 +548,34 @@ FROM OPENJSON(@__ints_0) WITH ([value] int '$') AS [i] """); } + public override async Task Parameter_collection_ImmutableArray_of_ints_Contains_int(bool async) + { + await base.Parameter_collection_ImmutableArray_of_ints_Contains_int(async); + + AssertSql( + """ +@ints='[10,999]' (Nullable = false) (Size = 4000) + +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].[NullableWrappedId], [p].[NullableWrappedIdWithNullableComparer], [p].[String], [p].[Strings], [p].[WrappedId] +FROM [PrimitiveCollectionsEntity] AS [p] +WHERE [p].[Int] IN ( + SELECT [i].[value] + FROM OPENJSON(@ints) WITH ([value] int '$') AS [i] +) +""", + // + """ +@ints='[10,999]' (Nullable = false) (Size = 4000) + +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].[NullableWrappedId], [p].[NullableWrappedIdWithNullableComparer], [p].[String], [p].[Strings], [p].[WrappedId] +FROM [PrimitiveCollectionsEntity] AS [p] +WHERE [p].[Int] NOT IN ( + SELECT [i].[value] + FROM OPENJSON(@ints) WITH ([value] int '$') AS [i] +) +"""); + } + public override async Task Parameter_collection_of_ints_Contains_nullable_int(bool async) { await base.Parameter_collection_of_ints_Contains_nullable_int(async); diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/PrimitiveCollectionsQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/PrimitiveCollectionsQuerySqliteTest.cs index ce27814d118..74396448cf9 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/PrimitiveCollectionsQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/PrimitiveCollectionsQuerySqliteTest.cs @@ -538,6 +538,34 @@ FROM json_each(@__ints_0) AS "i" """); } + public override async Task Parameter_collection_ImmutableArray_of_ints_Contains_int(bool async) + { + await base.Parameter_collection_ImmutableArray_of_ints_Contains_int(async); + + AssertSql( + """ +@ints='[10,999]' (Nullable = false) (Size = 8) + +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"."NullableWrappedId", "p"."NullableWrappedIdWithNullableComparer", "p"."String", "p"."Strings", "p"."WrappedId" +FROM "PrimitiveCollectionsEntity" AS "p" +WHERE "p"."Int" IN ( + SELECT "i"."value" + FROM json_each(@ints) AS "i" +) +""", + // + """ +@ints='[10,999]' (Nullable = false) (Size = 8) + +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"."NullableWrappedId", "p"."NullableWrappedIdWithNullableComparer", "p"."String", "p"."Strings", "p"."WrappedId" +FROM "PrimitiveCollectionsEntity" AS "p" +WHERE "p"."Int" NOT IN ( + SELECT "i"."value" + FROM json_each(@ints) AS "i" +) +"""); + } + public override async Task Parameter_collection_of_ints_Contains_nullable_int(bool async) { await base.Parameter_collection_of_ints_Contains_nullable_int(async); From 74150409d69449c4da36125c56330d420c214e9a Mon Sep 17 00:00:00 2001 From: Jiri Cincura Date: Mon, 2 Dec 2024 16:44:47 +0100 Subject: [PATCH 2/3] Added quirks --- ...ryableMethodNormalizingExpressionVisitor.cs | 5 ++++- src/EFCore/Query/QueryRootProcessor.cs | 18 ++++++++++++------ 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/src/EFCore/Query/Internal/QueryableMethodNormalizingExpressionVisitor.cs b/src/EFCore/Query/Internal/QueryableMethodNormalizingExpressionVisitor.cs index f5c1db2329e..7a43eab9d98 100644 --- a/src/EFCore/Query/Internal/QueryableMethodNormalizingExpressionVisitor.cs +++ b/src/EFCore/Query/Internal/QueryableMethodNormalizingExpressionVisitor.cs @@ -20,6 +20,9 @@ public class QueryableMethodNormalizingExpressionVisitor : ExpressionVisitor private readonly SelectManyVerifyingExpressionVisitor _selectManyVerifyingExpressionVisitor = new(); private readonly GroupJoinConvertingExpressionVisitor _groupJoinConvertingExpressionVisitor = new(); + private static readonly bool UseOldBehavior35102 = + AppContext.TryGetSwitch("Microsoft.EntityFrameworkCore.Issue35102", out var enabled35102) && enabled35102; + /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to /// the same compatibility standards as public APIs. It may be changed or removed without notice in @@ -489,7 +492,7 @@ private Expression TryConvertCollectionContainsToQueryableContains(MethodCallExp var sourceType = methodCallExpression.Method.DeclaringType!.GetGenericArguments()[0]; - var objectExpression = methodCallExpression.Object!.Type.IsValueType + var objectExpression = methodCallExpression.Object!.Type.IsValueType && !UseOldBehavior35102 ? Expression.Convert(methodCallExpression.Object!, typeof(IEnumerable<>).MakeGenericType(sourceType)) : methodCallExpression.Object!; diff --git a/src/EFCore/Query/QueryRootProcessor.cs b/src/EFCore/Query/QueryRootProcessor.cs index af0dc5b5e1f..79b6597476c 100644 --- a/src/EFCore/Query/QueryRootProcessor.cs +++ b/src/EFCore/Query/QueryRootProcessor.cs @@ -13,6 +13,9 @@ public class QueryRootProcessor : ExpressionVisitor { private readonly QueryCompilationContext _queryCompilationContext; + private static readonly bool UseOldBehavior35102 = + AppContext.TryGetSwitch("Microsoft.EntityFrameworkCore.Issue35102", out var enabled35102) && enabled35102; + /// /// Creates a new instance of the class with associated query provider. /// @@ -87,13 +90,16 @@ private Expression VisitQueryRootCandidate(Expression expression, Type elementCl { var candidateExpression = expression; - // In case the collection was value type, in order to call methods like AsQueryable, - // we need to convert it to IEnumerable which requires boxing. - // We do that with Convert expression which we need to unwrap here. - if (expression is UnaryExpression { NodeType: ExpressionType.Convert } convertExpression - && convertExpression.Type.GetGenericTypeDefinition() == typeof(IEnumerable<>)) + if (!UseOldBehavior35102) { - candidateExpression = convertExpression.Operand; + // In case the collection was value type, in order to call methods like AsQueryable, + // we need to convert it to IEnumerable which requires boxing. + // We do that with Convert expression which we need to unwrap here. + if (expression is UnaryExpression { NodeType: ExpressionType.Convert } convertExpression + && convertExpression.Type.GetGenericTypeDefinition() == typeof(IEnumerable<>)) + { + candidateExpression = convertExpression.Operand; + } } switch (candidateExpression) From 43558a4f13ae9779d3b6d2813b36c72220a2bc10 Mon Sep 17 00:00:00 2001 From: Jiri Cincura Date: Mon, 2 Dec 2024 18:29:41 +0100 Subject: [PATCH 3/3] Backport test fixes. --- .../Query/PrimitiveCollectionsQueryCosmosTest.cs | 8 ++++---- .../PrimitiveCollectionsQueryOldSqlServerTest.cs | 4 ++-- .../PrimitiveCollectionsQuerySqlServer160Test.cs | 12 ++++++------ ...PrimitiveCollectionsQuerySqlServerJsonTypeTest.cs | 8 ++++---- .../Query/PrimitiveCollectionsQuerySqlServerTest.cs | 12 ++++++------ .../Query/PrimitiveCollectionsQuerySqliteTest.cs | 12 ++++++------ 6 files changed, 28 insertions(+), 28 deletions(-) diff --git a/test/EFCore.Cosmos.FunctionalTests/Query/PrimitiveCollectionsQueryCosmosTest.cs b/test/EFCore.Cosmos.FunctionalTests/Query/PrimitiveCollectionsQueryCosmosTest.cs index f6bde5ef400..ea203a234b2 100644 --- a/test/EFCore.Cosmos.FunctionalTests/Query/PrimitiveCollectionsQueryCosmosTest.cs +++ b/test/EFCore.Cosmos.FunctionalTests/Query/PrimitiveCollectionsQueryCosmosTest.cs @@ -627,19 +627,19 @@ public override Task Parameter_collection_ImmutableArray_of_ints_Contains_int(bo AssertSql( """ -@ints='[10,999]' +@__ints_0='[10,999]' SELECT VALUE c FROM root c -WHERE ARRAY_CONTAINS(@ints, c["Int"]) +WHERE ARRAY_CONTAINS(@__ints_0, c["Int"]) """, // """ -@ints='[10,999]' +@__ints_0='[10,999]' SELECT VALUE c FROM root c -WHERE NOT(ARRAY_CONTAINS(@ints, c["Int"])) +WHERE NOT(ARRAY_CONTAINS(@__ints_0, c["Int"])) """); }); diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQueryOldSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQueryOldSqlServerTest.cs index fd1b12ba4f8..1041c1e10c1 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQueryOldSqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQueryOldSqlServerTest.cs @@ -504,13 +504,13 @@ public override async Task Parameter_collection_ImmutableArray_of_ints_Contains_ AssertSql( """ -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].[NullableWrappedId], [p].[NullableWrappedIdWithNullableComparer], [p].[String], [p].[Strings], [p].[WrappedId] +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 [p].[Int] IN (10, 999) """, // """ -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].[NullableWrappedId], [p].[NullableWrappedIdWithNullableComparer], [p].[String], [p].[Strings], [p].[WrappedId] +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 [p].[Int] NOT IN (10, 999) """); diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServer160Test.cs b/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServer160Test.cs index 220713d1bc4..9aea6357ba3 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServer160Test.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServer160Test.cs @@ -531,24 +531,24 @@ public override async Task Parameter_collection_ImmutableArray_of_ints_Contains_ AssertSql( """ -@ints='[10,999]' (Nullable = false) (Size = 4000) +@__ints_0='[10,999]' (Nullable = false) (Size = 4000) -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].[NullableWrappedId], [p].[NullableWrappedIdWithNullableComparer], [p].[String], [p].[Strings], [p].[WrappedId] +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 [p].[Int] IN ( SELECT [i].[value] - FROM OPENJSON(@ints) WITH ([value] int '$') AS [i] + FROM OPENJSON(@__ints_0) WITH ([value] int '$') AS [i] ) """, // """ -@ints='[10,999]' (Nullable = false) (Size = 4000) +@__ints_0='[10,999]' (Nullable = false) (Size = 4000) -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].[NullableWrappedId], [p].[NullableWrappedIdWithNullableComparer], [p].[String], [p].[Strings], [p].[WrappedId] +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 [p].[Int] NOT IN ( SELECT [i].[value] - FROM OPENJSON(@ints) WITH ([value] int '$') AS [i] + FROM OPENJSON(@__ints_0) WITH ([value] int '$') AS [i] ) """); } diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServerJsonTypeTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServerJsonTypeTest.cs index ee5010eeaf2..29656d04fe6 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServerJsonTypeTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServerJsonTypeTest.cs @@ -547,24 +547,24 @@ public override async Task Parameter_collection_ImmutableArray_of_ints_Contains_ AssertSql( """ -@ints='[10,999]' (Nullable = false) (Size = 4000) +@__ints_0='[10,999]' (Nullable = false) (Size = 4000) 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 [p].[Int] IN ( SELECT [i].[value] - FROM OPENJSON(@ints) WITH ([value] int '$') AS [i] + FROM OPENJSON(@__ints_0) WITH ([value] int '$') AS [i] ) """, // """ -@ints='[10,999]' (Nullable = false) (Size = 4000) +@__ints_0='[10,999]' (Nullable = false) (Size = 4000) 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 [p].[Int] NOT IN ( SELECT [i].[value] - FROM OPENJSON(@ints) WITH ([value] int '$') AS [i] + FROM OPENJSON(@__ints_0) WITH ([value] int '$') AS [i] ) """); } diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServerTest.cs index 6c15c9e3668..0708539aaa5 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/PrimitiveCollectionsQuerySqlServerTest.cs @@ -554,24 +554,24 @@ public override async Task Parameter_collection_ImmutableArray_of_ints_Contains_ AssertSql( """ -@ints='[10,999]' (Nullable = false) (Size = 4000) +@__ints_0='[10,999]' (Nullable = false) (Size = 4000) -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].[NullableWrappedId], [p].[NullableWrappedIdWithNullableComparer], [p].[String], [p].[Strings], [p].[WrappedId] +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 [p].[Int] IN ( SELECT [i].[value] - FROM OPENJSON(@ints) WITH ([value] int '$') AS [i] + FROM OPENJSON(@__ints_0) WITH ([value] int '$') AS [i] ) """, // """ -@ints='[10,999]' (Nullable = false) (Size = 4000) +@__ints_0='[10,999]' (Nullable = false) (Size = 4000) -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].[NullableWrappedId], [p].[NullableWrappedIdWithNullableComparer], [p].[String], [p].[Strings], [p].[WrappedId] +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 [p].[Int] NOT IN ( SELECT [i].[value] - FROM OPENJSON(@ints) WITH ([value] int '$') AS [i] + FROM OPENJSON(@__ints_0) WITH ([value] int '$') AS [i] ) """); } diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/PrimitiveCollectionsQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/PrimitiveCollectionsQuerySqliteTest.cs index 74396448cf9..58b6bb73a75 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/PrimitiveCollectionsQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/PrimitiveCollectionsQuerySqliteTest.cs @@ -544,24 +544,24 @@ public override async Task Parameter_collection_ImmutableArray_of_ints_Contains_ AssertSql( """ -@ints='[10,999]' (Nullable = false) (Size = 8) +@__ints_0='[10,999]' (Nullable = false) (Size = 8) -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"."NullableWrappedId", "p"."NullableWrappedIdWithNullableComparer", "p"."String", "p"."Strings", "p"."WrappedId" +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 "p"."Int" IN ( SELECT "i"."value" - FROM json_each(@ints) AS "i" + FROM json_each(@__ints_0) AS "i" ) """, // """ -@ints='[10,999]' (Nullable = false) (Size = 8) +@__ints_0='[10,999]' (Nullable = false) (Size = 8) -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"."NullableWrappedId", "p"."NullableWrappedIdWithNullableComparer", "p"."String", "p"."Strings", "p"."WrappedId" +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 "p"."Int" NOT IN ( SELECT "i"."value" - FROM json_each(@ints) AS "i" + FROM json_each(@__ints_0) AS "i" ) """); }