diff --git a/src/EFCore.Relational/Query/SqlExpressions/SelectExpression.cs b/src/EFCore.Relational/Query/SqlExpressions/SelectExpression.cs
index b510c493bd2..c07ef8d2c48 100644
--- a/src/EFCore.Relational/Query/SqlExpressions/SelectExpression.cs
+++ b/src/EFCore.Relational/Query/SqlExpressions/SelectExpression.cs
@@ -920,8 +920,8 @@ static Expression RemoveConvert(Expression expression)
var actualParentIdentifier = _identifier.Take(outerSelectExpression._identifier.Count).ToList();
for (var j = 0; j < actualParentIdentifier.Count; j++)
{
- AppendOrdering(new OrderingExpression(actualParentIdentifier[j].Column, ascending: true));
- outerSelectExpression.AppendOrdering(
+ AppendOrderingInternal(new OrderingExpression(actualParentIdentifier[j].Column, ascending: true));
+ outerSelectExpression.AppendOrderingInternal(
new OrderingExpression(outerSelectExpression._identifier[j].Column, ascending: true));
}
@@ -1860,6 +1860,11 @@ private static void PopulateGroupByTerms(
/// An ordering expression to use for ordering.
public void ApplyOrdering(OrderingExpression orderingExpression)
{
+ if (Limit is SqlConstantExpression { Value: 1 })
+ {
+ return;
+ }
+
if (IsDistinct
|| Limit != null
|| Offset != null)
@@ -1877,14 +1882,21 @@ public void ApplyOrdering(OrderingExpression orderingExpression)
/// An ordering expression to use for ordering.
public void AppendOrdering(OrderingExpression orderingExpression)
{
- if (!_orderings.Any(o => o.Expression.Equals(orderingExpression.Expression)))
+ if (Limit is SqlConstantExpression { Value: 1 })
{
- AppendOrderingInternal(orderingExpression);
+ return;
}
+
+ AppendOrderingInternal(orderingExpression);
}
private void AppendOrderingInternal(OrderingExpression orderingExpression)
- => _orderings.Add(orderingExpression.Update(orderingExpression.Expression));
+ {
+ if (!_orderings.Any(o => o.Expression.Equals(orderingExpression.Expression)))
+ {
+ _orderings.Add(orderingExpression);
+ }
+ }
///
/// Reverses the existing orderings on the .
diff --git a/test/EFCore.Cosmos.FunctionalTests/Query/NorthwindSelectQueryCosmosTest.cs b/test/EFCore.Cosmos.FunctionalTests/Query/NorthwindSelectQueryCosmosTest.cs
index b05fbdf7475..1729032d122 100644
--- a/test/EFCore.Cosmos.FunctionalTests/Query/NorthwindSelectQueryCosmosTest.cs
+++ b/test/EFCore.Cosmos.FunctionalTests/Query/NorthwindSelectQueryCosmosTest.cs
@@ -722,6 +722,15 @@ public override async Task Project_single_element_from_collection_with_OrderBy_T
AssertSql();
}
+ public override async Task Project_single_element_from_collection_with_OrderBy_Take_OrderBy_and_FirstOrDefault(bool async)
+ {
+ // Cosmos client evaluation. Issue #17246.
+ await AssertTranslationFailed(
+ () => base.Project_single_element_from_collection_with_OrderBy_Take_OrderBy_and_FirstOrDefault(async));
+
+ AssertSql();
+ }
+
public override async Task Project_single_element_from_collection_with_OrderBy_Take_and_FirstOrDefault_with_parameter(bool async)
{
// Cosmos client evaluation. Issue #17246.
diff --git a/test/EFCore.Specification.Tests/Query/NorthwindSelectQueryTestBase.cs b/test/EFCore.Specification.Tests/Query/NorthwindSelectQueryTestBase.cs
index cbd036ad513..83c1812aaee 100644
--- a/test/EFCore.Specification.Tests/Query/NorthwindSelectQueryTestBase.cs
+++ b/test/EFCore.Specification.Tests/Query/NorthwindSelectQueryTestBase.cs
@@ -1017,6 +1017,14 @@ public virtual Task Project_single_element_from_collection_with_OrderBy_Take_and
async,
ss => ss.Set().Select(c => c.Orders.OrderBy(o => o.OrderID).Select(o => o.CustomerID).Take(1).FirstOrDefault()));
+ [ConditionalTheory]
+ [MemberData(nameof(IsAsyncData))]
+ public virtual Task Project_single_element_from_collection_with_OrderBy_Take_OrderBy_and_FirstOrDefault(bool async)
+ => AssertQuery(
+ async,
+ ss => ss.Set().Select(
+ c => c.Orders.OrderBy(o => o.OrderID).Take(1).OrderBy(o => o.OrderDate).FirstOrDefault()));
+
[ConditionalTheory]
[MemberData(nameof(IsAsyncData))]
public virtual Task Project_single_element_from_collection_with_OrderBy_Skip_and_FirstOrDefault(bool async)
diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsQuerySqlServer160Test.cs b/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsQuerySqlServer160Test.cs
index 69f02149536..95aac4827b3 100644
--- a/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsQuerySqlServer160Test.cs
+++ b/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsQuerySqlServer160Test.cs
@@ -67,12 +67,8 @@ where l1.Id < 3
AssertSql(
"""
SELECT (
- SELECT TOP(1) [l1].[Name]
- FROM (
- SELECT TOP(1) [l0].[Id], [l0].[Name]
- FROM [LevelThree] AS [l0]
- ) AS [l1]
- ORDER BY [l1].[Id])
+ SELECT TOP(1) [l0].[Name]
+ FROM [LevelThree] AS [l0])
FROM [LevelOne] AS [l]
WHERE [l].[Id] < 3
""");
diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsQuerySqlServerTest.cs
index 16b4f166b45..92465352e8e 100644
--- a/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsQuerySqlServerTest.cs
+++ b/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsQuerySqlServerTest.cs
@@ -67,12 +67,8 @@ where l1.Id < 3
AssertSql(
"""
SELECT (
- SELECT TOP(1) [l1].[Name]
- FROM (
- SELECT TOP(1) [l0].[Id], [l0].[Name]
- FROM [LevelThree] AS [l0]
- ) AS [l1]
- ORDER BY [l1].[Id])
+ SELECT TOP(1) [l0].[Name]
+ FROM [LevelThree] AS [l0])
FROM [LevelOne] AS [l]
WHERE [l].[Id] < 3
""");
diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsSharedTypeQuerySqlServer160Test.cs b/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsSharedTypeQuerySqlServer160Test.cs
index 075eaf6fffa..31de2a01c62 100644
--- a/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsSharedTypeQuerySqlServer160Test.cs
+++ b/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsSharedTypeQuerySqlServer160Test.cs
@@ -85,31 +85,25 @@ where l1.Id < 3
AssertSql(
"""
SELECT (
- SELECT TOP(1) [s].[Level3_Name]
- FROM (
- SELECT TOP(1) [l4].[Id], [l4].[Level2_Required_Id], [l4].[Level3_Name], [l4].[OneToMany_Required_Inverse3Id]
- FROM [Level1] AS [l0]
- LEFT JOIN (
- SELECT [l1].[Id], [l1].[OneToOne_Required_PK_Date], [l1].[Level1_Required_Id], [l1].[OneToMany_Required_Inverse2Id]
- FROM [Level1] AS [l1]
- 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
- ) AS [l2] ON [l0].[Id] = CASE
- WHEN [l2].[OneToOne_Required_PK_Date] IS NOT NULL AND [l2].[Level1_Required_Id] IS NOT NULL AND [l2].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l2].[Id]
- END
- LEFT JOIN (
- SELECT [l3].[Id], [l3].[Level2_Required_Id], [l3].[Level3_Name], [l3].[OneToMany_Required_Inverse3Id]
- FROM [Level1] AS [l3]
- WHERE [l3].[Level2_Required_Id] IS NOT NULL AND [l3].[OneToMany_Required_Inverse3Id] IS NOT NULL
- ) AS [l4] ON CASE
- WHEN [l2].[OneToOne_Required_PK_Date] IS NOT NULL AND [l2].[Level1_Required_Id] IS NOT NULL AND [l2].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l2].[Id]
- END = CASE
- WHEN [l4].[Level2_Required_Id] IS NOT NULL AND [l4].[OneToMany_Required_Inverse3Id] IS NOT NULL THEN [l4].[Id]
- END
- WHERE [l2].[OneToOne_Required_PK_Date] IS NOT NULL AND [l2].[Level1_Required_Id] IS NOT NULL AND [l2].[OneToMany_Required_Inverse2Id] IS NOT NULL AND [l4].[Level2_Required_Id] IS NOT NULL AND [l4].[OneToMany_Required_Inverse3Id] IS NOT NULL
- ) AS [s]
- ORDER BY CASE
- WHEN [s].[Level2_Required_Id] IS NOT NULL AND [s].[OneToMany_Required_Inverse3Id] IS NOT NULL THEN [s].[Id]
- END)
+ SELECT TOP(1) [l4].[Level3_Name]
+ FROM [Level1] AS [l0]
+ LEFT JOIN (
+ SELECT [l1].[Id], [l1].[OneToOne_Required_PK_Date], [l1].[Level1_Required_Id], [l1].[OneToMany_Required_Inverse2Id]
+ FROM [Level1] AS [l1]
+ 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
+ ) AS [l2] ON [l0].[Id] = CASE
+ WHEN [l2].[OneToOne_Required_PK_Date] IS NOT NULL AND [l2].[Level1_Required_Id] IS NOT NULL AND [l2].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l2].[Id]
+ END
+ LEFT JOIN (
+ SELECT [l3].[Id], [l3].[Level2_Required_Id], [l3].[Level3_Name], [l3].[OneToMany_Required_Inverse3Id]
+ FROM [Level1] AS [l3]
+ WHERE [l3].[Level2_Required_Id] IS NOT NULL AND [l3].[OneToMany_Required_Inverse3Id] IS NOT NULL
+ ) AS [l4] ON CASE
+ WHEN [l2].[OneToOne_Required_PK_Date] IS NOT NULL AND [l2].[Level1_Required_Id] IS NOT NULL AND [l2].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l2].[Id]
+ END = CASE
+ WHEN [l4].[Level2_Required_Id] IS NOT NULL AND [l4].[OneToMany_Required_Inverse3Id] IS NOT NULL THEN [l4].[Id]
+ END
+ WHERE [l2].[OneToOne_Required_PK_Date] IS NOT NULL AND [l2].[Level1_Required_Id] IS NOT NULL AND [l2].[OneToMany_Required_Inverse2Id] IS NOT NULL AND [l4].[Level2_Required_Id] IS NOT NULL AND [l4].[OneToMany_Required_Inverse3Id] IS NOT NULL)
FROM [Level1] AS [l]
WHERE [l].[Id] < 3
""");
diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsSharedTypeQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsSharedTypeQuerySqlServerTest.cs
index c6edb779d49..c2686849f93 100644
--- a/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsSharedTypeQuerySqlServerTest.cs
+++ b/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsSharedTypeQuerySqlServerTest.cs
@@ -87,31 +87,25 @@ where l1.Id < 3
AssertSql(
"""
SELECT (
- SELECT TOP(1) [s].[Level3_Name]
- FROM (
- SELECT TOP(1) [l4].[Id], [l4].[Level2_Required_Id], [l4].[Level3_Name], [l4].[OneToMany_Required_Inverse3Id]
- FROM [Level1] AS [l0]
- LEFT JOIN (
- SELECT [l1].[Id], [l1].[OneToOne_Required_PK_Date], [l1].[Level1_Required_Id], [l1].[OneToMany_Required_Inverse2Id]
- FROM [Level1] AS [l1]
- 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
- ) AS [l2] ON [l0].[Id] = CASE
- WHEN [l2].[OneToOne_Required_PK_Date] IS NOT NULL AND [l2].[Level1_Required_Id] IS NOT NULL AND [l2].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l2].[Id]
- END
- LEFT JOIN (
- SELECT [l3].[Id], [l3].[Level2_Required_Id], [l3].[Level3_Name], [l3].[OneToMany_Required_Inverse3Id]
- FROM [Level1] AS [l3]
- WHERE [l3].[Level2_Required_Id] IS NOT NULL AND [l3].[OneToMany_Required_Inverse3Id] IS NOT NULL
- ) AS [l4] ON CASE
- WHEN [l2].[OneToOne_Required_PK_Date] IS NOT NULL AND [l2].[Level1_Required_Id] IS NOT NULL AND [l2].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l2].[Id]
- END = CASE
- WHEN [l4].[Level2_Required_Id] IS NOT NULL AND [l4].[OneToMany_Required_Inverse3Id] IS NOT NULL THEN [l4].[Id]
- END
- WHERE [l2].[OneToOne_Required_PK_Date] IS NOT NULL AND [l2].[Level1_Required_Id] IS NOT NULL AND [l2].[OneToMany_Required_Inverse2Id] IS NOT NULL AND [l4].[Level2_Required_Id] IS NOT NULL AND [l4].[OneToMany_Required_Inverse3Id] IS NOT NULL
- ) AS [s]
- ORDER BY CASE
- WHEN [s].[Level2_Required_Id] IS NOT NULL AND [s].[OneToMany_Required_Inverse3Id] IS NOT NULL THEN [s].[Id]
- END)
+ SELECT TOP(1) [l4].[Level3_Name]
+ FROM [Level1] AS [l0]
+ LEFT JOIN (
+ SELECT [l1].[Id], [l1].[OneToOne_Required_PK_Date], [l1].[Level1_Required_Id], [l1].[OneToMany_Required_Inverse2Id]
+ FROM [Level1] AS [l1]
+ 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
+ ) AS [l2] ON [l0].[Id] = CASE
+ WHEN [l2].[OneToOne_Required_PK_Date] IS NOT NULL AND [l2].[Level1_Required_Id] IS NOT NULL AND [l2].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l2].[Id]
+ END
+ LEFT JOIN (
+ SELECT [l3].[Id], [l3].[Level2_Required_Id], [l3].[Level3_Name], [l3].[OneToMany_Required_Inverse3Id]
+ FROM [Level1] AS [l3]
+ WHERE [l3].[Level2_Required_Id] IS NOT NULL AND [l3].[OneToMany_Required_Inverse3Id] IS NOT NULL
+ ) AS [l4] ON CASE
+ WHEN [l2].[OneToOne_Required_PK_Date] IS NOT NULL AND [l2].[Level1_Required_Id] IS NOT NULL AND [l2].[OneToMany_Required_Inverse2Id] IS NOT NULL THEN [l2].[Id]
+ END = CASE
+ WHEN [l4].[Level2_Required_Id] IS NOT NULL AND [l4].[OneToMany_Required_Inverse3Id] IS NOT NULL THEN [l4].[Id]
+ END
+ WHERE [l2].[OneToOne_Required_PK_Date] IS NOT NULL AND [l2].[Level1_Required_Id] IS NOT NULL AND [l2].[OneToMany_Required_Inverse2Id] IS NOT NULL AND [l4].[Level2_Required_Id] IS NOT NULL AND [l4].[OneToMany_Required_Inverse3Id] IS NOT NULL)
FROM [Level1] AS [l]
WHERE [l].[Id] < 3
""");
diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindSelectQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindSelectQuerySqlServerTest.cs
index 922fa23af79..acfa05fe027 100644
--- a/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindSelectQuerySqlServerTest.cs
+++ b/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindSelectQuerySqlServerTest.cs
@@ -768,6 +768,25 @@ FROM [Customers] AS [c]
""");
}
+ public override async Task Project_single_element_from_collection_with_OrderBy_Take_OrderBy_and_FirstOrDefault(bool async)
+ {
+ await base.Project_single_element_from_collection_with_OrderBy_Take_OrderBy_and_FirstOrDefault(async);
+
+ AssertSql(
+ """
+SELECT [o1].[OrderID], [o1].[CustomerID], [o1].[EmployeeID], [o1].[OrderDate]
+FROM [Customers] AS [c]
+LEFT JOIN (
+ SELECT [o0].[OrderID], [o0].[CustomerID], [o0].[EmployeeID], [o0].[OrderDate]
+ FROM (
+ SELECT [o].[OrderID], [o].[CustomerID], [o].[EmployeeID], [o].[OrderDate], ROW_NUMBER() OVER(PARTITION BY [o].[CustomerID] ORDER BY [o].[OrderID]) AS [row]
+ FROM [Orders] AS [o]
+ ) AS [o0]
+ WHERE [o0].[row] <= 1
+) AS [o1] ON [c].[CustomerID] = [o1].[CustomerID]
+""");
+ }
+
public override async Task Project_single_element_from_collection_with_OrderBy_Skip_and_FirstOrDefault(bool async)
{
await base.Project_single_element_from_collection_with_OrderBy_Skip_and_FirstOrDefault(async);