Skip to content

Commit 85c1c35

Browse files
authored
Count > 0 normalized to Any should also work on ICollection (#35381)
* Count > 0 normalized to .Any should also work on ICollection * call genertictypedefinition only once
1 parent 02d37a2 commit 85c1c35

12 files changed

+56
-54
lines changed

src/EFCore/Query/Internal/QueryableMethodNormalizingExpressionVisitor.cs

+4-2
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,10 @@ protected override Expression VisitBinary(BinaryExpression binaryExpression)
7070
},
7171
Right: ConstantExpression { Value: 0 }
7272
}
73-
when (member.DeclaringType.GetGenericTypeDefinition().GetInterfaces().Any(
74-
x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof(ICollection<>)))
73+
when member.DeclaringType.GetGenericTypeDefinition() is Type genericTypeDefinition
74+
&& (genericTypeDefinition == typeof(ICollection<>)
75+
|| genericTypeDefinition.GetInterfaces()
76+
.Any(x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof(ICollection<>)))
7577
=> VisitMethodCall(
7678
Expression.Call(
7779
EnumerableMethods.AnyWithoutPredicate.MakeGenericMethod(source.Type.GetSequenceType()),

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

+6-6
Original file line numberDiff line numberDiff line change
@@ -1369,10 +1369,10 @@ public override async Task Where_navigation_property_to_collection(bool async)
13691369
SELECT [l].[Id], [l].[Date], [l].[Name], [l].[OneToMany_Optional_Self_Inverse1Id], [l].[OneToMany_Required_Self_Inverse1Id], [l].[OneToOne_Optional_Self1Id]
13701370
FROM [LevelOne] AS [l]
13711371
LEFT JOIN [LevelTwo] AS [l0] ON [l].[Id] = [l0].[Level1_Required_Id]
1372-
WHERE (
1373-
SELECT COUNT(*)
1372+
WHERE EXISTS (
1373+
SELECT 1
13741374
FROM [LevelThree] AS [l1]
1375-
WHERE [l0].[Id] IS NOT NULL AND [l0].[Id] = [l1].[OneToMany_Optional_Inverse3Id]) > 0
1375+
WHERE [l0].[Id] IS NOT NULL AND [l0].[Id] = [l1].[OneToMany_Optional_Inverse3Id])
13761376
""");
13771377
}
13781378

@@ -1385,10 +1385,10 @@ public override async Task Where_navigation_property_to_collection2(bool async)
13851385
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]
13861386
FROM [LevelThree] AS [l]
13871387
INNER JOIN [LevelTwo] AS [l0] ON [l].[Level2_Required_Id] = [l0].[Id]
1388-
WHERE (
1389-
SELECT COUNT(*)
1388+
WHERE EXISTS (
1389+
SELECT 1
13901390
FROM [LevelThree] AS [l1]
1391-
WHERE [l0].[Id] = [l1].[OneToMany_Optional_Inverse3Id]) > 0
1391+
WHERE [l0].[Id] = [l1].[OneToMany_Optional_Inverse3Id])
13921392
""");
13931393
}
13941394

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

+7-7
Original file line numberDiff line numberDiff line change
@@ -5031,7 +5031,7 @@ public override async Task Where_navigation_property_to_collection2(bool async)
50315031
await base.Where_navigation_property_to_collection2(async);
50325032

50335033
AssertSql(
5034-
"""
5034+
"""
50355035
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]
50365036
FROM [Level1] AS [l]
50375037
LEFT JOIN (
@@ -5057,16 +5057,16 @@ WHERE [l4].[OneToOne_Required_PK_Date] IS NOT NULL AND [l4].[Level1_Required_Id]
50575057
) AS [l5] ON [l3].[Level2_Required_Id] = CASE
50585058
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]
50595059
END
5060-
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 (
5061-
SELECT COUNT(*)
5060+
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 (
5061+
SELECT 1
50625062
FROM [Level1] AS [l6]
50635063
WHERE [l6].[Level2_Required_Id] IS NOT NULL AND [l6].[OneToMany_Required_Inverse3Id] IS NOT NULL AND CASE
50645064
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]
50655065
END IS NOT NULL AND (CASE
50665066
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]
50675067
END = [l6].[OneToMany_Optional_Inverse3Id] OR (CASE
50685068
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]
5069-
END IS NULL AND [l6].[OneToMany_Optional_Inverse3Id] IS NULL))) > 0
5069+
END IS NULL AND [l6].[OneToMany_Optional_Inverse3Id] IS NULL)))
50705070
""");
50715071
}
50725072

@@ -6257,16 +6257,16 @@ LEFT JOIN (
62576257
FROM [Level1] AS [l0]
62586258
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
62596259
) AS [l1] ON [l].[Id] = [l1].[Level1_Required_Id]
6260-
WHERE (
6261-
SELECT COUNT(*)
6260+
WHERE EXISTS (
6261+
SELECT 1
62626262
FROM [Level1] AS [l2]
62636263
WHERE [l2].[Level2_Required_Id] IS NOT NULL AND [l2].[OneToMany_Required_Inverse3Id] IS NOT NULL AND CASE
62646264
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]
62656265
END IS NOT NULL AND (CASE
62666266
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]
62676267
END = [l2].[OneToMany_Optional_Inverse3Id] OR (CASE
62686268
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]
6269-
END IS NULL AND [l2].[OneToMany_Optional_Inverse3Id] IS NULL))) > 0
6269+
END IS NULL AND [l2].[OneToMany_Optional_Inverse3Id] IS NULL)))
62706270
""");
62716271
}
62726272

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

+3-3
Original file line numberDiff line numberDiff line change
@@ -87,11 +87,11 @@ public override async Task Skip_navigation_count_without_predicate(bool async)
8787
"""
8888
SELECT [e].[Id], [e].[Name]
8989
FROM [EntityOnes] AS [e]
90-
WHERE (
91-
SELECT COUNT(*)
90+
WHERE EXISTS (
91+
SELECT 1
9292
FROM [JoinOneSelfPayload] AS [j]
9393
INNER JOIN [EntityOnes] AS [e0] ON [j].[LeftId] = [e0].[Id]
94-
WHERE [e].[Id] = [j].[RightId]) > 0
94+
WHERE [e].[Id] = [j].[RightId])
9595
""");
9696
}
9797

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

+3-3
Original file line numberDiff line numberDiff line change
@@ -86,11 +86,11 @@ public override async Task Skip_navigation_count_without_predicate(bool async)
8686
"""
8787
SELECT [e].[Id], [e].[Name]
8888
FROM [EntityOnes] AS [e]
89-
WHERE (
90-
SELECT COUNT(*)
89+
WHERE EXISTS (
90+
SELECT 1
9191
FROM [JoinOneSelfPayload] AS [j]
9292
INNER JOIN [EntityOnes] AS [e0] ON [j].[LeftId] = [e0].[Id]
93-
WHERE [e].[Id] = [j].[RightId]) > 0
93+
WHERE [e].[Id] = [j].[RightId])
9494
""");
9595
}
9696

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

+3-3
Original file line numberDiff line numberDiff line change
@@ -256,10 +256,10 @@ LEFT JOIN (
256256
FROM [Order] AS [o1]
257257
LEFT JOIN [OrderDetail] AS [o2] ON [o1].[ClientId] = [o2].[OrderClientId] AND [o1].[Id] = [o2].[OrderId]
258258
) AS [s] ON [o].[Id] = [s].[ClientId]
259-
WHERE (
260-
SELECT COUNT(*)
259+
WHERE EXISTS (
260+
SELECT 1
261261
FROM [Order] AS [o0]
262-
WHERE [o].[Id] = [o0].[ClientId]) > 0
262+
WHERE [o].[Id] = [o0].[ClientId])
263263
ORDER BY [o].[Id], [s].[ClientId], [s].[Id], [s].[OrderClientId], [s].[OrderId]
264264
""");
265265
}

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

+6-6
Original file line numberDiff line numberDiff line change
@@ -90,11 +90,11 @@ public override async Task Skip_navigation_count_without_predicate(bool async)
9090
"""
9191
SELECT [e].[Id], [e].[Name]
9292
FROM [EntityOnes] AS [e]
93-
WHERE (
94-
SELECT COUNT(*)
93+
WHERE EXISTS (
94+
SELECT 1
9595
FROM [JoinOneSelfPayload] AS [j]
9696
INNER JOIN [EntityOnes] AS [e0] ON [j].[LeftId] = [e0].[Id]
97-
WHERE [e].[Id] = [j].[RightId]) > 0
97+
WHERE [e].[Id] = [j].[RightId])
9898
""");
9999
}
100100

@@ -2176,11 +2176,11 @@ public override async Task Skip_navigation_count_without_predicate_unidirectiona
21762176
"""
21772177
SELECT [u].[Id], [u].[Name]
21782178
FROM [UnidirectionalEntityOnes] AS [u]
2179-
WHERE (
2180-
SELECT COUNT(*)
2179+
WHERE EXISTS (
2180+
SELECT 1
21812181
FROM [UnidirectionalJoinOneSelfPayload] AS [u0]
21822182
INNER JOIN [UnidirectionalEntityOnes] AS [u1] ON [u0].[LeftId] = [u1].[Id]
2183-
WHERE [u].[Id] = [u0].[RightId]) > 0
2183+
WHERE [u].[Id] = [u0].[RightId])
21842184
""");
21852185
}
21862186

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

+6-6
Original file line numberDiff line numberDiff line change
@@ -90,11 +90,11 @@ public override async Task Skip_navigation_count_without_predicate(bool async)
9090
"""
9191
SELECT [e].[Id], [e].[Name]
9292
FROM [EntityOnes] AS [e]
93-
WHERE (
94-
SELECT COUNT(*)
93+
WHERE EXISTS (
94+
SELECT 1
9595
FROM [JoinOneSelfPayload] AS [j]
9696
INNER JOIN [EntityOnes] AS [e0] ON [j].[LeftId] = [e0].[Id]
97-
WHERE [e].[Id] = [j].[RightId]) > 0
97+
WHERE [e].[Id] = [j].[RightId])
9898
""");
9999
}
100100

@@ -2177,11 +2177,11 @@ public override async Task Skip_navigation_count_without_predicate_unidirectiona
21772177
"""
21782178
SELECT [u].[Id], [u].[Name]
21792179
FROM [UnidirectionalEntityOnes] AS [u]
2180-
WHERE (
2181-
SELECT COUNT(*)
2180+
WHERE EXISTS (
2181+
SELECT 1
21822182
FROM [UnidirectionalJoinOneSelfPayload] AS [u0]
21832183
INNER JOIN [UnidirectionalEntityOnes] AS [u1] ON [u0].[LeftId] = [u1].[Id]
2184-
WHERE [u].[Id] = [u0].[RightId]) > 0
2184+
WHERE [u].[Id] = [u0].[RightId])
21852185
""");
21862186
}
21872187

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

+6-6
Original file line numberDiff line numberDiff line change
@@ -91,11 +91,11 @@ public override async Task Skip_navigation_count_without_predicate(bool async)
9191
"""
9292
SELECT [e].[Id], [e].[Name]
9393
FROM [EntityOnes] AS [e]
94-
WHERE (
95-
SELECT COUNT(*)
94+
WHERE EXISTS (
95+
SELECT 1
9696
FROM [JoinOneSelfPayload] AS [j]
9797
INNER JOIN [EntityOnes] AS [e0] ON [j].[LeftId] = [e0].[Id]
98-
WHERE [e].[Id] = [j].[RightId]) > 0
98+
WHERE [e].[Id] = [j].[RightId])
9999
""");
100100
}
101101

@@ -2125,11 +2125,11 @@ public override async Task Skip_navigation_count_without_predicate_unidirectiona
21252125
"""
21262126
SELECT [u].[Id], [u].[Name]
21272127
FROM [UnidirectionalEntityOnes] AS [u]
2128-
WHERE (
2129-
SELECT COUNT(*)
2128+
WHERE EXISTS (
2129+
SELECT 1
21302130
FROM [UnidirectionalJoinOneSelfPayload] AS [u0]
21312131
INNER JOIN [UnidirectionalEntityOnes] AS [u1] ON [u0].[LeftId] = [u1].[Id]
2132-
WHERE [u].[Id] = [u0].[RightId]) > 0
2132+
WHERE [u].[Id] = [u0].[RightId])
21332133
""");
21342134
}
21352135

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

+6-6
Original file line numberDiff line numberDiff line change
@@ -90,11 +90,11 @@ public override async Task Skip_navigation_count_without_predicate(bool async)
9090
"""
9191
SELECT [e].[Id], [e].[Name]
9292
FROM [EntityOnes] AS [e]
93-
WHERE (
94-
SELECT COUNT(*)
93+
WHERE EXISTS (
94+
SELECT 1
9595
FROM [JoinOneSelfPayload] AS [j]
9696
INNER JOIN [EntityOnes] AS [e0] ON [j].[LeftId] = [e0].[Id]
97-
WHERE [e].[Id] = [j].[RightId]) > 0
97+
WHERE [e].[Id] = [j].[RightId])
9898
""");
9999
}
100100

@@ -2125,11 +2125,11 @@ public override async Task Skip_navigation_count_without_predicate_unidirectiona
21252125
"""
21262126
SELECT [u].[Id], [u].[Name]
21272127
FROM [UnidirectionalEntityOnes] AS [u]
2128-
WHERE (
2129-
SELECT COUNT(*)
2128+
WHERE EXISTS (
2129+
SELECT 1
21302130
FROM [UnidirectionalJoinOneSelfPayload] AS [u0]
21312131
INNER JOIN [UnidirectionalEntityOnes] AS [u1] ON [u0].[LeftId] = [u1].[Id]
2132-
WHERE [u].[Id] = [u0].[RightId]) > 0
2132+
WHERE [u].[Id] = [u0].[RightId])
21332133
""");
21342134
}
21352135

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

+3-3
Original file line numberDiff line numberDiff line change
@@ -120,11 +120,11 @@ public override async Task Skip_navigation_count_without_predicate(bool async)
120120
"""
121121
SELECT [e].[Id], [e].[Name], [e].[PeriodEnd], [e].[PeriodStart]
122122
FROM [EntityOnes] FOR SYSTEM_TIME AS OF '2010-01-01T00:00:00.0000000' AS [e]
123-
WHERE (
124-
SELECT COUNT(*)
123+
WHERE EXISTS (
124+
SELECT 1
125125
FROM [JoinOneSelfPayload] FOR SYSTEM_TIME AS OF '2010-01-01T00:00:00.0000000' AS [j]
126126
INNER JOIN [EntityOnes] FOR SYSTEM_TIME AS OF '2010-01-01T00:00:00.0000000' AS [e0] ON [j].[LeftId] = [e0].[Id]
127-
WHERE [e].[Id] = [j].[RightId]) > 0
127+
WHERE [e].[Id] = [j].[RightId])
128128
""");
129129
}
130130

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

+3-3
Original file line numberDiff line numberDiff line change
@@ -273,10 +273,10 @@ LEFT JOIN (
273273
FROM [Order] FOR SYSTEM_TIME AS OF '2010-01-01T00:00:00.0000000' AS [o1]
274274
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]
275275
) AS [s] ON [o].[Id] = [s].[ClientId]
276-
WHERE (
277-
SELECT COUNT(*)
276+
WHERE EXISTS (
277+
SELECT 1
278278
FROM [Order] FOR SYSTEM_TIME AS OF '2010-01-01T00:00:00.0000000' AS [o0]
279-
WHERE [o].[Id] = [o0].[ClientId]) > 0
279+
WHERE [o].[Id] = [o0].[ClientId])
280280
ORDER BY [o].[Id], [s].[ClientId], [s].[Id], [s].[OrderClientId], [s].[OrderId]
281281
""");
282282
}

0 commit comments

Comments
 (0)