diff --git a/src/EFCore/Query/Internal/QueryableMethodNormalizingExpressionVisitor.cs b/src/EFCore/Query/Internal/QueryableMethodNormalizingExpressionVisitor.cs index 261ce2c2705..0b594f4c716 100644 --- a/src/EFCore/Query/Internal/QueryableMethodNormalizingExpressionVisitor.cs +++ b/src/EFCore/Query/Internal/QueryableMethodNormalizingExpressionVisitor.cs @@ -70,8 +70,10 @@ protected override Expression VisitBinary(BinaryExpression binaryExpression) }, Right: ConstantExpression { Value: 0 } } - when (member.DeclaringType.GetGenericTypeDefinition().GetInterfaces().Any( - x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof(ICollection<>))) + when member.DeclaringType.GetGenericTypeDefinition() is Type genericTypeDefinition + && (genericTypeDefinition == typeof(ICollection<>) + || genericTypeDefinition.GetInterfaces() + .Any(x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof(ICollection<>))) => VisitMethodCall( Expression.Call( EnumerableMethods.AnyWithoutPredicate.MakeGenericMethod(source.Type.GetSequenceType()), diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsQuerySqlServerTest.cs index 16b4f166b45..a6e73d27634 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsQuerySqlServerTest.cs @@ -1369,10 +1369,10 @@ public override async Task Where_navigation_property_to_collection(bool async) SELECT [l].[Id], [l].[Date], [l].[Name], [l].[OneToMany_Optional_Self_Inverse1Id], [l].[OneToMany_Required_Self_Inverse1Id], [l].[OneToOne_Optional_Self1Id] FROM [LevelOne] AS [l] LEFT JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[Level1_Required_Id] -WHERE ( - SELECT COUNT(*) +WHERE EXISTS ( + SELECT 1 FROM [LevelThree] AS [l1] - WHERE [l0].[Id] IS NOT NULL AND [l0].[Id] = [l1].[OneToMany_Optional_Inverse3Id]) > 0 + WHERE [l0].[Id] IS NOT NULL AND [l0].[Id] = [l1].[OneToMany_Optional_Inverse3Id]) """); } @@ -1385,10 +1385,10 @@ public override async Task Where_navigation_property_to_collection2(bool async) SELECT [l].[Id], [l].[Level2_Optional_Id], [l].[Level2_Required_Id], [l].[Name], [l].[OneToMany_Optional_Inverse3Id], [l].[OneToMany_Optional_Self_Inverse3Id], [l].[OneToMany_Required_Inverse3Id], [l].[OneToMany_Required_Self_Inverse3Id], [l].[OneToOne_Optional_PK_Inverse3Id], [l].[OneToOne_Optional_Self3Id] FROM [LevelThree] AS [l] INNER JOIN [LevelTwo] AS [l0] ON [l].[Level2_Required_Id] = [l0].[Id] -WHERE ( - SELECT COUNT(*) +WHERE EXISTS ( + SELECT 1 FROM [LevelThree] AS [l1] - WHERE [l0].[Id] = [l1].[OneToMany_Optional_Inverse3Id]) > 0 + WHERE [l0].[Id] = [l1].[OneToMany_Optional_Inverse3Id]) """); } diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsSharedTypeQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsSharedTypeQuerySqlServerTest.cs index c6edb779d49..c0d53dacabf 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsSharedTypeQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsSharedTypeQuerySqlServerTest.cs @@ -5031,7 +5031,7 @@ public override async Task Where_navigation_property_to_collection2(bool async) await base.Where_navigation_property_to_collection2(async); AssertSql( - """ +""" SELECT [l3].[Id], [l3].[Level2_Optional_Id], [l3].[Level2_Required_Id], [l3].[Level3_Name], [l3].[OneToMany_Optional_Inverse3Id], [l3].[OneToMany_Required_Inverse3Id], [l3].[OneToOne_Optional_PK_Inverse3Id] FROM [Level1] AS [l] LEFT JOIN ( @@ -5057,8 +5057,8 @@ WHERE [l4].[OneToOne_Required_PK_Date] IS NOT NULL AND [l4].[Level1_Required_Id] ) AS [l5] ON [l3].[Level2_Required_Id] = CASE WHEN [l5].[OneToOne_Required_PK_Date] IS NOT NULL AND [l5].[Level1_Required_Id] IS NOT NULL AND [l5].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l5].[Id] END -WHERE [l1].[OneToOne_Required_PK_Date] IS NOT NULL AND [l1].[Level1_Required_Id] IS NOT NULL AND [l1].[OneToMany_Required_Inverse2Id] IS NOT NULL AND [l3].[Level2_Required_Id] IS NOT NULL AND [l3].[OneToMany_Required_Inverse3Id] IS NOT NULL AND ( - SELECT COUNT(*) +WHERE [l1].[OneToOne_Required_PK_Date] IS NOT NULL AND [l1].[Level1_Required_Id] IS NOT NULL AND [l1].[OneToMany_Required_Inverse2Id] IS NOT NULL AND [l3].[Level2_Required_Id] IS NOT NULL AND [l3].[OneToMany_Required_Inverse3Id] IS NOT NULL AND EXISTS ( + SELECT 1 FROM [Level1] AS [l6] WHERE [l6].[Level2_Required_Id] IS NOT NULL AND [l6].[OneToMany_Required_Inverse3Id] IS NOT NULL AND CASE WHEN [l5].[OneToOne_Required_PK_Date] IS NOT NULL AND [l5].[Level1_Required_Id] IS NOT NULL AND [l5].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l5].[Id] @@ -5066,7 +5066,7 @@ END IS NOT NULL AND (CASE WHEN [l5].[OneToOne_Required_PK_Date] IS NOT NULL AND [l5].[Level1_Required_Id] IS NOT NULL AND [l5].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l5].[Id] END = [l6].[OneToMany_Optional_Inverse3Id] OR (CASE WHEN [l5].[OneToOne_Required_PK_Date] IS NOT NULL AND [l5].[Level1_Required_Id] IS NOT NULL AND [l5].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l5].[Id] - END IS NULL AND [l6].[OneToMany_Optional_Inverse3Id] IS NULL))) > 0 + END IS NULL AND [l6].[OneToMany_Optional_Inverse3Id] IS NULL))) """); } @@ -6257,8 +6257,8 @@ LEFT JOIN ( FROM [Level1] AS [l0] WHERE [l0].[OneToOne_Required_PK_Date] IS NOT NULL AND [l0].[Level1_Required_Id] IS NOT NULL AND [l0].[OneToMany_Required_Inverse2Id] IS NOT NULL ) AS [l1] ON [l].[Id] = [l1].[Level1_Required_Id] -WHERE ( - SELECT COUNT(*) +WHERE EXISTS ( + SELECT 1 FROM [Level1] AS [l2] WHERE [l2].[Level2_Required_Id] IS NOT NULL AND [l2].[OneToMany_Required_Inverse3Id] IS NOT NULL AND CASE WHEN [l1].[OneToOne_Required_PK_Date] IS NOT NULL AND [l1].[Level1_Required_Id] IS NOT NULL AND [l1].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l1].[Id] @@ -6266,7 +6266,7 @@ END IS NOT NULL AND (CASE WHEN [l1].[OneToOne_Required_PK_Date] IS NOT NULL AND [l1].[Level1_Required_Id] IS NOT NULL AND [l1].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l1].[Id] END = [l2].[OneToMany_Optional_Inverse3Id] OR (CASE WHEN [l1].[OneToOne_Required_PK_Date] IS NOT NULL AND [l1].[Level1_Required_Id] IS NOT NULL AND [l1].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l1].[Id] - END IS NULL AND [l2].[OneToMany_Optional_Inverse3Id] IS NULL))) > 0 + END IS NULL AND [l2].[OneToMany_Optional_Inverse3Id] IS NULL))) """); } diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/ManyToManyNoTrackingQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/ManyToManyNoTrackingQuerySqlServerTest.cs index 386c1fe322a..fb764af04ac 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/ManyToManyNoTrackingQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/ManyToManyNoTrackingQuerySqlServerTest.cs @@ -87,11 +87,11 @@ public override async Task Skip_navigation_count_without_predicate(bool async) """ SELECT [e].[Id], [e].[Name] FROM [EntityOnes] AS [e] -WHERE ( - SELECT COUNT(*) +WHERE EXISTS ( + SELECT 1 FROM [JoinOneSelfPayload] AS [j] INNER JOIN [EntityOnes] AS [e0] ON [j].[LeftId] = [e0].[Id] - WHERE [e].[Id] = [j].[RightId]) > 0 + WHERE [e].[Id] = [j].[RightId]) """); } diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/ManyToManyQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/ManyToManyQuerySqlServerTest.cs index 222bfd862ef..4e62ab1a847 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/ManyToManyQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/ManyToManyQuerySqlServerTest.cs @@ -86,11 +86,11 @@ public override async Task Skip_navigation_count_without_predicate(bool async) """ SELECT [e].[Id], [e].[Name] FROM [EntityOnes] AS [e] -WHERE ( - SELECT COUNT(*) +WHERE EXISTS ( + SELECT 1 FROM [JoinOneSelfPayload] AS [j] INNER JOIN [EntityOnes] AS [e0] ON [j].[LeftId] = [e0].[Id] - WHERE [e].[Id] = [j].[RightId]) > 0 + WHERE [e].[Id] = [j].[RightId]) """); } diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/OwnedQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/OwnedQuerySqlServerTest.cs index ce80f77977f..05a96675e12 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/OwnedQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/OwnedQuerySqlServerTest.cs @@ -256,10 +256,10 @@ LEFT JOIN ( FROM [Order] AS [o1] LEFT JOIN [OrderDetail] AS [o2] ON [o1].[ClientId] = [o2].[OrderClientId] AND [o1].[Id] = [o2].[OrderId] ) AS [s] ON [o].[Id] = [s].[ClientId] -WHERE ( - SELECT COUNT(*) +WHERE EXISTS ( + SELECT 1 FROM [Order] AS [o0] - WHERE [o].[Id] = [o0].[ClientId]) > 0 + WHERE [o].[Id] = [o0].[ClientId]) ORDER BY [o].[Id], [s].[ClientId], [s].[Id], [s].[OrderClientId], [s].[OrderId] """); } diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/TPCManyToManyNoTrackingQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/TPCManyToManyNoTrackingQuerySqlServerTest.cs index 5ec6900fde0..bff52f8be45 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/TPCManyToManyNoTrackingQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/TPCManyToManyNoTrackingQuerySqlServerTest.cs @@ -90,11 +90,11 @@ public override async Task Skip_navigation_count_without_predicate(bool async) """ SELECT [e].[Id], [e].[Name] FROM [EntityOnes] AS [e] -WHERE ( - SELECT COUNT(*) +WHERE EXISTS ( + SELECT 1 FROM [JoinOneSelfPayload] AS [j] INNER JOIN [EntityOnes] AS [e0] ON [j].[LeftId] = [e0].[Id] - WHERE [e].[Id] = [j].[RightId]) > 0 + WHERE [e].[Id] = [j].[RightId]) """); } @@ -2178,11 +2178,11 @@ public override async Task Skip_navigation_count_without_predicate_unidirectiona """ SELECT [u].[Id], [u].[Name] FROM [UnidirectionalEntityOnes] AS [u] -WHERE ( - SELECT COUNT(*) +WHERE EXISTS ( + SELECT 1 FROM [UnidirectionalJoinOneSelfPayload] AS [u0] INNER JOIN [UnidirectionalEntityOnes] AS [u1] ON [u0].[LeftId] = [u1].[Id] - WHERE [u].[Id] = [u0].[RightId]) > 0 + WHERE [u].[Id] = [u0].[RightId]) """); } diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/TPCManyToManyQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/TPCManyToManyQuerySqlServerTest.cs index 10a704eec28..229fc14ef7b 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/TPCManyToManyQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/TPCManyToManyQuerySqlServerTest.cs @@ -90,11 +90,11 @@ public override async Task Skip_navigation_count_without_predicate(bool async) """ SELECT [e].[Id], [e].[Name] FROM [EntityOnes] AS [e] -WHERE ( - SELECT COUNT(*) +WHERE EXISTS ( + SELECT 1 FROM [JoinOneSelfPayload] AS [j] INNER JOIN [EntityOnes] AS [e0] ON [j].[LeftId] = [e0].[Id] - WHERE [e].[Id] = [j].[RightId]) > 0 + WHERE [e].[Id] = [j].[RightId]) """); } @@ -2179,11 +2179,11 @@ public override async Task Skip_navigation_count_without_predicate_unidirectiona """ SELECT [u].[Id], [u].[Name] FROM [UnidirectionalEntityOnes] AS [u] -WHERE ( - SELECT COUNT(*) +WHERE EXISTS ( + SELECT 1 FROM [UnidirectionalJoinOneSelfPayload] AS [u0] INNER JOIN [UnidirectionalEntityOnes] AS [u1] ON [u0].[LeftId] = [u1].[Id] - WHERE [u].[Id] = [u0].[RightId]) > 0 + WHERE [u].[Id] = [u0].[RightId]) """); } diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/TPTManyToManyNoTrackingQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/TPTManyToManyNoTrackingQuerySqlServerTest.cs index bc17e65bd09..d91e6e7e1e9 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/TPTManyToManyNoTrackingQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/TPTManyToManyNoTrackingQuerySqlServerTest.cs @@ -91,11 +91,11 @@ public override async Task Skip_navigation_count_without_predicate(bool async) """ SELECT [e].[Id], [e].[Name] FROM [EntityOnes] AS [e] -WHERE ( - SELECT COUNT(*) +WHERE EXISTS ( + SELECT 1 FROM [JoinOneSelfPayload] AS [j] INNER JOIN [EntityOnes] AS [e0] ON [j].[LeftId] = [e0].[Id] - WHERE [e].[Id] = [j].[RightId]) > 0 + WHERE [e].[Id] = [j].[RightId]) """); } @@ -2127,11 +2127,11 @@ public override async Task Skip_navigation_count_without_predicate_unidirectiona """ SELECT [u].[Id], [u].[Name] FROM [UnidirectionalEntityOnes] AS [u] -WHERE ( - SELECT COUNT(*) +WHERE EXISTS ( + SELECT 1 FROM [UnidirectionalJoinOneSelfPayload] AS [u0] INNER JOIN [UnidirectionalEntityOnes] AS [u1] ON [u0].[LeftId] = [u1].[Id] - WHERE [u].[Id] = [u0].[RightId]) > 0 + WHERE [u].[Id] = [u0].[RightId]) """); } diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/TPTManyToManyQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/TPTManyToManyQuerySqlServerTest.cs index 125860a2071..87821f2e4b0 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/TPTManyToManyQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/TPTManyToManyQuerySqlServerTest.cs @@ -90,11 +90,11 @@ public override async Task Skip_navigation_count_without_predicate(bool async) """ SELECT [e].[Id], [e].[Name] FROM [EntityOnes] AS [e] -WHERE ( - SELECT COUNT(*) +WHERE EXISTS ( + SELECT 1 FROM [JoinOneSelfPayload] AS [j] INNER JOIN [EntityOnes] AS [e0] ON [j].[LeftId] = [e0].[Id] - WHERE [e].[Id] = [j].[RightId]) > 0 + WHERE [e].[Id] = [j].[RightId]) """); } @@ -2127,11 +2127,11 @@ public override async Task Skip_navigation_count_without_predicate_unidirectiona """ SELECT [u].[Id], [u].[Name] FROM [UnidirectionalEntityOnes] AS [u] -WHERE ( - SELECT COUNT(*) +WHERE EXISTS ( + SELECT 1 FROM [UnidirectionalJoinOneSelfPayload] AS [u0] INNER JOIN [UnidirectionalEntityOnes] AS [u1] ON [u0].[LeftId] = [u1].[Id] - WHERE [u].[Id] = [u0].[RightId]) > 0 + WHERE [u].[Id] = [u0].[RightId]) """); } diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/TemporalManyToManyQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/TemporalManyToManyQuerySqlServerTest.cs index a2d2ce977bc..0e6a6d4e2c7 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/TemporalManyToManyQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/TemporalManyToManyQuerySqlServerTest.cs @@ -120,11 +120,11 @@ public override async Task Skip_navigation_count_without_predicate(bool async) """ SELECT [e].[Id], [e].[Name], [e].[PeriodEnd], [e].[PeriodStart] FROM [EntityOnes] FOR SYSTEM_TIME AS OF '2010-01-01T00:00:00.0000000' AS [e] -WHERE ( - SELECT COUNT(*) +WHERE EXISTS ( + SELECT 1 FROM [JoinOneSelfPayload] FOR SYSTEM_TIME AS OF '2010-01-01T00:00:00.0000000' AS [j] INNER JOIN [EntityOnes] FOR SYSTEM_TIME AS OF '2010-01-01T00:00:00.0000000' AS [e0] ON [j].[LeftId] = [e0].[Id] - WHERE [e].[Id] = [j].[RightId]) > 0 + WHERE [e].[Id] = [j].[RightId]) """); } diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/TemporalOwnedQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/TemporalOwnedQuerySqlServerTest.cs index 5b8b46a392a..78860365e07 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/TemporalOwnedQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/TemporalOwnedQuerySqlServerTest.cs @@ -273,10 +273,10 @@ LEFT JOIN ( FROM [Order] FOR SYSTEM_TIME AS OF '2010-01-01T00:00:00.0000000' AS [o1] LEFT JOIN [OrderDetail] FOR SYSTEM_TIME AS OF '2010-01-01T00:00:00.0000000' AS [o2] ON [o1].[ClientId] = [o2].[OrderClientId] AND [o1].[Id] = [o2].[OrderId] ) AS [s] ON [o].[Id] = [s].[ClientId] -WHERE ( - SELECT COUNT(*) +WHERE EXISTS ( + SELECT 1 FROM [Order] FOR SYSTEM_TIME AS OF '2010-01-01T00:00:00.0000000' AS [o0] - WHERE [o].[Id] = [o0].[ClientId]) > 0 + WHERE [o].[Id] = [o0].[ClientId]) ORDER BY [o].[Id], [s].[ClientId], [s].[Id], [s].[OrderClientId], [s].[OrderId] """); }