Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1548,6 +1548,14 @@ static IReadOnlyList<IProperty> GetMappedKeyProperties(IKey key)
public void ReplaceProjection(IReadOnlyDictionary<ProjectionMember, Expression> projectionMapping)
{
_projectionMapping.Clear();

// A projection is represented either as a projection-member mapping or as a client-projection list, never both
// (see GetProjection). When switching to a member mapping, any client projections left over from a previous
// projection (e.g. a prior Select that fell back to index-based binding) must be cleared, otherwise the stale
// client projections take precedence in ApplyProjection and the member-based shaper fails to remap. See #31209.
_clientProjections.Clear();
_aliasForClientProjections.Clear();

foreach (var (projectionMember, expression) in projectionMapping)
{
Check.DebugAssert(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,4 +84,28 @@ public override Task GroupBy_Select_Entire_Entity_Order(bool async)
[Theory(Skip = "Issue#31209")]
public override Task GroupBy_Select_Entire_Entity_Where(bool async)
=> base.GroupBy_Select_Entire_Entity_Where(async);

[Theory(Skip = "Issue#31209")]
public override Task GroupBy_Select_Entire_Entity_Select(bool async)
=> base.GroupBy_Select_Entire_Entity_Select(async);

[Theory(Skip = "Issue#31209")]
public override Task GroupBy_Select_Entire_Entity_Where_Select(bool async)
=> base.GroupBy_Select_Entire_Entity_Where_Select(async);

[Theory(Skip = "Issue#31209")]
public override Task GroupBy_Select_Entire_Entity_FirstOrDefault_Where(bool async)
=> base.GroupBy_Select_Entire_Entity_FirstOrDefault_Where(async);

[Theory(Skip = "Issue#31209")]
public override Task GroupBy_ResultSelector_Entire_Entity_Where(bool async)
=> base.GroupBy_ResultSelector_Entire_Entity_Where(async);

[Theory(Skip = "Issue#31209")]
public override Task GroupBy_Select_Entire_Entity_GroupBy(bool async)
=> base.GroupBy_Select_Entire_Entity_GroupBy(async);

[Theory(Skip = "Issue#31209")]
public override Task GroupBy_Select_Entire_Entity_composite_key_Select(bool async)
=> base.GroupBy_Select_Entire_Entity_composite_key_Select(async);
}
Original file line number Diff line number Diff line change
Expand Up @@ -1957,7 +1957,7 @@ public virtual Task GroupBy_Select_Entire_Entity_Where(bool async) // #31209
.Select(a => a.First())
.Where(x => x.EmployeeID == 6u));

[Theory(Skip = "Issue#31209"), MemberData(nameof(IsAsyncData))]
[Theory, MemberData(nameof(IsAsyncData))]
public virtual Task GroupBy_Select_Entire_Entity_Where_Select(bool async) // #31209
=> AssertQuery(
async,
Expand All @@ -1966,7 +1966,7 @@ public virtual Task GroupBy_Select_Entire_Entity_Where_Select(bool async) // #31
.Where(x => x.OrderID > 10)
.Select(r => r.EmployeeID));

[Theory(Skip = "Issue#31209"), MemberData(nameof(IsAsyncData))]
[Theory, MemberData(nameof(IsAsyncData))]
public virtual Task GroupBy_Select_Entire_Entity_Select(bool async) // #31209
=> AssertQuery(
async,
Expand Down Expand Up @@ -1995,6 +1995,41 @@ public virtual Task GroupBy_Select_Anonymous_Type_With_Entire_Entity(bool async)
Item = g.OrderByDescending(x => x.OrderDate).FirstOrDefault(),
}).Where(x => x.Item != null));

[Theory, MemberData(nameof(IsAsyncData))]
public virtual Task GroupBy_Select_Entire_Entity_FirstOrDefault_Where(bool async) // #31209
=> AssertQuery(
async,
ss => ss.Set<Order>().GroupBy(o => o.CustomerID)
.Select(g => g.OrderByDescending(o => o.OrderDate).FirstOrDefault())
.Where(r => r.EmployeeID == 5u));

[Theory, MemberData(nameof(IsAsyncData))]
public virtual Task GroupBy_ResultSelector_Entire_Entity_Where(bool async) // #31209
=> AssertQuery(
async,
ss => ss.Set<Order>().GroupBy(
o => o.CustomerID,
(k, es) => es.OrderByDescending(o => o.OrderDate).First())
.Where(r => r.EmployeeID == 6u));

[Theory, MemberData(nameof(IsAsyncData))]
public virtual Task GroupBy_Select_Entire_Entity_GroupBy(bool async) // #31209
=> AssertQuery(
async,
ss => ss.Set<Order>().GroupBy(o => new { o.CustomerID, o.EmployeeID })
.Select(g => g.First())
.GroupBy(o => o.EmployeeID)
.Select(g2 => new { g2.Key, Count = g2.Count() }),
elementSorter: e => e.Key);

[Theory, MemberData(nameof(IsAsyncData))]
public virtual Task GroupBy_Select_Entire_Entity_composite_key_Select(bool async) // #26748
=> AssertQuery(
async,
ss => ss.Set<Order>().GroupBy(o => new { o.CustomerID, o.EmployeeID })
.Select(g => g.First())
.Select(p => p.OrderID));

[Theory, MemberData(nameof(IsAsyncData))]
public virtual Task GroupBy_aggregate_join_with_group_result(bool async)
=> AssertQuery(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3085,14 +3085,127 @@ public override async Task GroupBy_Select_Entire_Entity_Where_Select(bool async)
{
await base.GroupBy_Select_Entire_Entity_Where_Select(async);

AssertSql();
AssertSql(
"""
SELECT (
SELECT TOP(1) [o1].[EmployeeID]
FROM [Orders] AS [o1]
WHERE [o].[OrderID] = [o1].[OrderID])
FROM [Orders] AS [o]
GROUP BY [o].[OrderID]
HAVING (
SELECT TOP(1) [o0].[OrderID]
FROM [Orders] AS [o0]
WHERE [o].[OrderID] = [o0].[OrderID]) > 10
""");
}

public override async Task GroupBy_Select_Entire_Entity_Select(bool async)
{
await base.GroupBy_Select_Entire_Entity_Select(async);

AssertSql();
AssertSql(
"""
SELECT (
SELECT TOP(1) [o0].[EmployeeID]
FROM [Orders] AS [o0]
WHERE [o].[OrderID] = [o0].[OrderID])
FROM [Orders] AS [o]
GROUP BY [o].[OrderID]
""");
}

public override async Task GroupBy_Select_Entire_Entity_FirstOrDefault_Where(bool async)
{
await base.GroupBy_Select_Entire_Entity_FirstOrDefault_Where(async);

AssertSql(
"""
SELECT [o4].[OrderID], [o4].[CustomerID], [o4].[EmployeeID], [o4].[OrderDate]
FROM (
SELECT [o].[CustomerID]
FROM [Orders] AS [o]
GROUP BY [o].[CustomerID]
HAVING (
SELECT TOP(1) [o1].[EmployeeID]
FROM [Orders] AS [o1]
WHERE [o].[CustomerID] = [o1].[CustomerID] OR ([o].[CustomerID] IS NULL AND [o1].[CustomerID] IS NULL)
ORDER BY [o1].[OrderDate] DESC) = 5
) AS [o2]
LEFT JOIN (
SELECT [o3].[OrderID], [o3].[CustomerID], [o3].[EmployeeID], [o3].[OrderDate]
FROM (
SELECT [o0].[OrderID], [o0].[CustomerID], [o0].[EmployeeID], [o0].[OrderDate], ROW_NUMBER() OVER(PARTITION BY [o0].[CustomerID] ORDER BY [o0].[OrderDate] DESC) AS [row]
FROM [Orders] AS [o0]
) AS [o3]
WHERE [o3].[row] <= 1
) AS [o4] ON [o2].[CustomerID] = [o4].[CustomerID]
""");
}

public override async Task GroupBy_ResultSelector_Entire_Entity_Where(bool async)
{
await base.GroupBy_ResultSelector_Entire_Entity_Where(async);

AssertSql(
"""
SELECT [o4].[OrderID], [o4].[CustomerID], [o4].[EmployeeID], [o4].[OrderDate]
FROM (
SELECT [o].[CustomerID]
FROM [Orders] AS [o]
GROUP BY [o].[CustomerID]
HAVING (
SELECT TOP(1) [o1].[EmployeeID]
FROM [Orders] AS [o1]
WHERE [o].[CustomerID] = [o1].[CustomerID] OR ([o].[CustomerID] IS NULL AND [o1].[CustomerID] IS NULL)
ORDER BY [o1].[OrderDate] DESC) = 6
) AS [o2]
LEFT JOIN (
SELECT [o3].[OrderID], [o3].[CustomerID], [o3].[EmployeeID], [o3].[OrderDate]
FROM (
SELECT [o0].[OrderID], [o0].[CustomerID], [o0].[EmployeeID], [o0].[OrderDate], ROW_NUMBER() OVER(PARTITION BY [o0].[CustomerID] ORDER BY [o0].[OrderDate] DESC) AS [row]
FROM [Orders] AS [o0]
) AS [o3]
WHERE [o3].[row] <= 1
) AS [o4] ON [o2].[CustomerID] = [o4].[CustomerID]
""");
}

public override async Task GroupBy_Select_Entire_Entity_GroupBy(bool async)
{
await base.GroupBy_Select_Entire_Entity_GroupBy(async);

AssertSql(
"""
SELECT [o2].[Key], COUNT(*) AS [Count]
FROM (
SELECT (
SELECT TOP(1) [o1].[EmployeeID]
FROM [Orders] AS [o1]
WHERE ([o0].[CustomerID] = [o1].[CustomerID] OR ([o0].[CustomerID] IS NULL AND [o1].[CustomerID] IS NULL)) AND ([o0].[EmployeeID] = [o1].[EmployeeID] OR ([o0].[EmployeeID] IS NULL AND [o1].[EmployeeID] IS NULL))) AS [Key]
FROM (
SELECT [o].[CustomerID], [o].[EmployeeID]
FROM [Orders] AS [o]
GROUP BY [o].[CustomerID], [o].[EmployeeID]
) AS [o0]
) AS [o2]
GROUP BY [o2].[Key]
""");
}

public override async Task GroupBy_Select_Entire_Entity_composite_key_Select(bool async)
{
await base.GroupBy_Select_Entire_Entity_composite_key_Select(async);

AssertSql(
"""
SELECT (
SELECT TOP(1) [o0].[OrderID]
FROM [Orders] AS [o0]
WHERE ([o].[CustomerID] = [o0].[CustomerID] OR ([o].[CustomerID] IS NULL AND [o0].[CustomerID] IS NULL)) AND ([o].[EmployeeID] = [o0].[EmployeeID] OR ([o].[EmployeeID] IS NULL AND [o0].[EmployeeID] IS NULL)))
FROM [Orders] AS [o]
GROUP BY [o].[CustomerID], [o].[EmployeeID]
""");
}

public override async Task GroupBy_Select_Entire_Entity_Order(bool async)
Expand Down
Loading