Skip to content

Commit 895be6c

Browse files
authored
[release/7.0] Fix split query over GroupBy over parameter (#30024) (#30030)
Fixes #30022
1 parent be8c0ef commit 895be6c

9 files changed

+155
-1
lines changed

src/EFCore.Relational/Properties/RelationalStrings.Designer.cs

+8
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/EFCore.Relational/Properties/RelationalStrings.resx

+3
Original file line numberDiff line numberDiff line change
@@ -899,6 +899,9 @@
899899
<data name="NoDbCommand" xml:space="preserve">
900900
<value>Cannot create a DbCommand for a non-relational query.</value>
901901
</data>
902+
<data name="NonConstantOrParameterAsInExpressionValues" xml:space="preserve">
903+
<value>Expression of type '{type}' isn't supported as the Values of an InExpression; only constants and parameters are supported.</value>
904+
</data>
902905
<data name="NoneRelationalTypeMappingOnARelationalTypeMappingSource" xml:space="preserve">
903906
<value>'FindMapping' was called on a 'RelationalTypeMappingSource' with a non-relational 'TypeMappingInfo'.</value>
904907
</data>

src/EFCore.Relational/Query/SqlExpressions/SelectExpression.Helper.cs

+6-1
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,9 @@ private sealed class SqlRemappingVisitor : ExpressionVisitor
162162
private readonly HashSet<SqlExpression> _correlatedTerms;
163163
private bool _groupByDiscovery;
164164

165+
private static readonly bool QuirkEnabled30022
166+
= AppContext.TryGetSwitch("Microsoft.EntityFrameworkCore.Issue30022", out var enabled) && enabled;
167+
165168
public SqlRemappingVisitor(
166169
Dictionary<SqlExpression, ColumnExpression> mappings,
167170
SelectExpression subquery,
@@ -210,7 +213,9 @@ when _groupByDiscovery
210213

211214
case SqlExpression sqlExpression
212215
when !_groupByDiscovery
213-
&& sqlExpression is not SqlConstantExpression or SqlParameterExpression
216+
&& (QuirkEnabled30022
217+
? sqlExpression is not SqlConstantExpression or SqlParameterExpression
218+
: sqlExpression is not SqlConstantExpression and not SqlParameterExpression)
214219
&& _correlatedTerms.Contains(sqlExpression):
215220
var outerColumn = _subquery.GenerateOuterColumn(_tableReferenceExpression, sqlExpression);
216221
_mappings[sqlExpression] = outerColumn;

test/EFCore.Specification.Tests/Query/ComplexNavigationsCollectionsQueryTestBase.cs

+20
Original file line numberDiff line numberDiff line change
@@ -2197,6 +2197,26 @@ public virtual Task Skip_Take_on_grouping_element_inside_collection_projection(b
21972197
});
21982198
});
21992199

2200+
[ConditionalTheory]
2201+
[MemberData(nameof(IsAsyncData))]
2202+
public virtual Task Collection_projection_over_GroupBy_over_parameter(bool async)
2203+
{
2204+
var validIds = new List<string> { "L1 01", "L1 02" };
2205+
2206+
return AssertQuery(
2207+
async,
2208+
ss => ss.Set<Level1>()
2209+
.Where(l1 => validIds.Contains(l1.Name))
2210+
.GroupBy(l => l.Date)
2211+
.Select(g => new { g.Key, Ids = g.Select(e => e.Id) }),
2212+
elementSorter: e => e.Key,
2213+
elementAsserter: (e, a) =>
2214+
{
2215+
AssertEqual(e.Key, a.Key);
2216+
AssertCollection(e.Ids, a.Ids);
2217+
});
2218+
}
2219+
22002220
[ConditionalTheory]
22012221
[MemberData(nameof(IsAsyncData))]
22022222
public virtual Task SelectMany_over_conditional_null_source(bool async)

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

+22
Original file line numberDiff line numberDiff line change
@@ -2319,6 +2319,28 @@ FROM [LevelOne] AS [l1]
23192319
""");
23202320
}
23212321

2322+
public override async Task Collection_projection_over_GroupBy_over_parameter(bool async)
2323+
{
2324+
await base.Collection_projection_over_GroupBy_over_parameter(async);
2325+
2326+
AssertSql(
2327+
"""
2328+
SELECT [t].[Date], [t0].[Id]
2329+
FROM (
2330+
SELECT [l].[Date]
2331+
FROM [LevelOne] AS [l]
2332+
WHERE [l].[Name] IN (N'L1 01', N'L1 02')
2333+
GROUP BY [l].[Date]
2334+
) AS [t]
2335+
LEFT JOIN (
2336+
SELECT [l0].[Id], [l0].[Date]
2337+
FROM [LevelOne] AS [l0]
2338+
WHERE [l0].[Name] IN (N'L1 01', N'L1 02')
2339+
) AS [t0] ON [t].[Date] = [t0].[Date]
2340+
ORDER BY [t].[Date]
2341+
""");
2342+
}
2343+
23222344
public override async Task Include_partially_added_before_Where_and_then_build_upon(bool async)
23232345
{
23242346
await base.Include_partially_added_before_Where_and_then_build_upon(async);

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

+22
Original file line numberDiff line numberDiff line change
@@ -3003,6 +3003,28 @@ FROM [Level1] AS [l1]
30033003
""");
30043004
}
30053005

3006+
public override async Task Collection_projection_over_GroupBy_over_parameter(bool async)
3007+
{
3008+
await base.Collection_projection_over_GroupBy_over_parameter(async);
3009+
3010+
AssertSql(
3011+
"""
3012+
SELECT [t].[Date], [t0].[Id]
3013+
FROM (
3014+
SELECT [l].[Date]
3015+
FROM [Level1] AS [l]
3016+
WHERE [l].[Name] IN (N'L1 01', N'L1 02')
3017+
GROUP BY [l].[Date]
3018+
) AS [t]
3019+
LEFT JOIN (
3020+
SELECT [l0].[Id], [l0].[Date]
3021+
FROM [Level1] AS [l0]
3022+
WHERE [l0].[Name] IN (N'L1 01', N'L1 02')
3023+
) AS [t0] ON [t].[Date] = [t0].[Date]
3024+
ORDER BY [t].[Date]
3025+
""");
3026+
}
3027+
30063028
public override async Task Filtered_include_is_considered_loaded(bool async)
30073029
{
30083030
await base.Filtered_include_is_considered_loaded(async);

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

+30
Original file line numberDiff line numberDiff line change
@@ -3728,6 +3728,36 @@ FROM [LevelOne] AS [l1]
37283728
""");
37293729
}
37303730

3731+
public override async Task Collection_projection_over_GroupBy_over_parameter(bool async)
3732+
{
3733+
await base.Collection_projection_over_GroupBy_over_parameter(async);
3734+
3735+
AssertSql(
3736+
"""
3737+
SELECT [l].[Date]
3738+
FROM [LevelOne] AS [l]
3739+
WHERE [l].[Name] IN (N'L1 01', N'L1 02')
3740+
GROUP BY [l].[Date]
3741+
ORDER BY [l].[Date]
3742+
""",
3743+
//
3744+
"""
3745+
SELECT [t0].[Id], [t].[Date]
3746+
FROM (
3747+
SELECT [l].[Date]
3748+
FROM [LevelOne] AS [l]
3749+
WHERE [l].[Name] IN (N'L1 01', N'L1 02')
3750+
GROUP BY [l].[Date]
3751+
) AS [t]
3752+
INNER JOIN (
3753+
SELECT [l0].[Id], [l0].[Date]
3754+
FROM [LevelOne] AS [l0]
3755+
WHERE [l0].[Name] IN (N'L1 01', N'L1 02')
3756+
) AS [t0] ON [t].[Date] = [t0].[Date]
3757+
ORDER BY [t].[Date]
3758+
""");
3759+
}
3760+
37313761
public override async Task Include_partially_added_before_Where_and_then_build_upon(bool async)
37323762
{
37333763
await base.Include_partially_added_before_Where_and_then_build_upon(async);

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

+22
Original file line numberDiff line numberDiff line change
@@ -2293,6 +2293,28 @@ LEFT JOIN (
22932293
""");
22942294
}
22952295

2296+
public override async Task Collection_projection_over_GroupBy_over_parameter(bool async)
2297+
{
2298+
await base.Collection_projection_over_GroupBy_over_parameter(async);
2299+
2300+
AssertSql(
2301+
"""
2302+
SELECT [t].[Date], [t0].[Id]
2303+
FROM (
2304+
SELECT [l].[Date]
2305+
FROM [LevelOne] FOR SYSTEM_TIME AS OF '2010-01-01T00:00:00.0000000' AS [l]
2306+
WHERE [l].[Name] IN (N'L1 01', N'L1 02')
2307+
GROUP BY [l].[Date]
2308+
) AS [t]
2309+
LEFT JOIN (
2310+
SELECT [l0].[Id], [l0].[Date]
2311+
FROM [LevelOne] FOR SYSTEM_TIME AS OF '2010-01-01T00:00:00.0000000' AS [l0]
2312+
WHERE [l0].[Name] IN (N'L1 01', N'L1 02')
2313+
) AS [t0] ON [t].[Date] = [t0].[Date]
2314+
ORDER BY [t].[Date]
2315+
""");
2316+
}
2317+
22962318
public override async Task Multiple_SelectMany_navigation_property_followed_by_select_collection_navigation(bool async)
22972319
{
22982320
await base.Multiple_SelectMany_navigation_property_followed_by_select_collection_navigation(async);

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

+22
Original file line numberDiff line numberDiff line change
@@ -3021,6 +3021,28 @@ LEFT JOIN (
30213021
""");
30223022
}
30233023

3024+
public override async Task Collection_projection_over_GroupBy_over_parameter(bool async)
3025+
{
3026+
await base.Collection_projection_over_GroupBy_over_parameter(async);
3027+
3028+
AssertSql(
3029+
"""
3030+
SELECT [t].[Date], [t0].[Id]
3031+
FROM (
3032+
SELECT [l].[Date]
3033+
FROM [Level1] FOR SYSTEM_TIME AS OF '2010-01-01T00:00:00.0000000' AS [l]
3034+
WHERE [l].[Name] IN (N'L1 01', N'L1 02')
3035+
GROUP BY [l].[Date]
3036+
) AS [t]
3037+
LEFT JOIN (
3038+
SELECT [l0].[Id], [l0].[Date]
3039+
FROM [Level1] FOR SYSTEM_TIME AS OF '2010-01-01T00:00:00.0000000' AS [l0]
3040+
WHERE [l0].[Name] IN (N'L1 01', N'L1 02')
3041+
) AS [t0] ON [t].[Date] = [t0].[Date]
3042+
ORDER BY [t].[Date]
3043+
""");
3044+
}
3045+
30243046
public override async Task Skip_Take_on_grouping_element_into_non_entity(bool async)
30253047
{
30263048
await base.Skip_Take_on_grouping_element_into_non_entity(async);

0 commit comments

Comments
 (0)