From 681cb54e215aa536c9ac5982524f3507761b944b Mon Sep 17 00:00:00 2001 From: Shay Rojansky Date: Tue, 9 Jun 2020 09:20:49 +0200 Subject: [PATCH] Move fake ORDER BY clause to SQL Server provider Closes #19031 --- .../Query/QuerySqlGenerator.cs | 4 ---- .../Internal/SqlServerQuerySqlGenerator.cs | 20 +++++++++++++++++++ .../NorthwindMiscellaneousQuerySqliteTest.cs | 1 - 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/EFCore.Relational/Query/QuerySqlGenerator.cs b/src/EFCore.Relational/Query/QuerySqlGenerator.cs index 028d05dc1db..1baba723a7c 100644 --- a/src/EFCore.Relational/Query/QuerySqlGenerator.cs +++ b/src/EFCore.Relational/Query/QuerySqlGenerator.cs @@ -798,10 +798,6 @@ protected virtual void GenerateOrderings([NotNull] SelectExpression selectExpres GenerateList(orderings, e => Visit(e)); } } - else if (selectExpression.Offset != null) - { - _relationalCommandBuilder.AppendLine().Append("ORDER BY (SELECT 1)"); - } } /// diff --git a/src/EFCore.SqlServer/Query/Internal/SqlServerQuerySqlGenerator.cs b/src/EFCore.SqlServer/Query/Internal/SqlServerQuerySqlGenerator.cs index 98a1908a287..baeeeace945 100644 --- a/src/EFCore.SqlServer/Query/Internal/SqlServerQuerySqlGenerator.cs +++ b/src/EFCore.SqlServer/Query/Internal/SqlServerQuerySqlGenerator.cs @@ -49,6 +49,26 @@ protected override void GenerateTop(SelectExpression selectExpression) } } + /// + /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to + /// the same compatibility standards as public APIs. It may be changed or removed without notice in + /// any release. You should only use it directly in your code with extreme caution and knowing that + /// doing so can result in application failures when updating to a new Entity Framework Core release. + /// + protected override void GenerateOrderings(SelectExpression selectExpression) + { + Check.NotNull(selectExpression, nameof(selectExpression)); + + base.GenerateOrderings(selectExpression); + + // In SQL Server, if an offset is specified, then an ORDER BY clause must also exist. + // Generate a fake one. + if (!selectExpression.Orderings.Any() && selectExpression.Offset != null) + { + Sql.AppendLine().Append("ORDER BY (SELECT 1)"); + } + } + /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to /// the same compatibility standards as public APIs. It may be changed or removed without notice in diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/NorthwindMiscellaneousQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/NorthwindMiscellaneousQuerySqliteTest.cs index a1361c4e8c8..f87906e07cd 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/NorthwindMiscellaneousQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/NorthwindMiscellaneousQuerySqliteTest.cs @@ -215,7 +215,6 @@ SELECT COUNT(*) FROM ( SELECT ""c"".""CustomerID"", ""c"".""Address"", ""c"".""City"", ""c"".""CompanyName"", ""c"".""ContactName"", ""c"".""ContactTitle"", ""c"".""Country"", ""c"".""Fax"", ""c"".""Phone"", ""c"".""PostalCode"", ""c"".""Region"" FROM ""Customers"" AS ""c"" - ORDER BY (SELECT 1) LIMIT -1 OFFSET @__p_0 ) AS ""t"""); }