From dbe3bf7e8991d8ba431ed8fdc03afc76853f9a5c Mon Sep 17 00:00:00 2001 From: Christopher Jolly Date: Wed, 8 Nov 2023 01:19:40 +0800 Subject: [PATCH] The DELETE statement in Jet doesn't take the TOP clause like SQL server. Limit the valid select expressions to those that do not use TOP. EF Core will then rewrite it into a WHERE EXISTS clause to use in the DELETE. Valid select expressions are able to be used directly in the DELETE/UPDATE --- ...yableMethodTranslatingExpressionVisitor.cs | 6 ++- .../Sql/Internal/JetQuerySqlGenerator.cs | 14 +++-- .../ComplexTypeBulkUpdatesJetTest.cs | 3 +- .../NonSharedModelBulkUpdatesJetTest.cs | 6 +-- .../NorthwindBulkUpdatesJetTest.cs | 51 ++++++++----------- .../TPHInheritanceBulkUpdatesJetTest.cs | 15 ++---- ...TPTFiltersInheritanceBulkUpdatesJetTest.cs | 6 +-- 7 files changed, 43 insertions(+), 58 deletions(-) diff --git a/src/EFCore.Jet/Query/Internal/JetQueryableMethodTranslatingExpressionVisitor.cs b/src/EFCore.Jet/Query/Internal/JetQueryableMethodTranslatingExpressionVisitor.cs index 1c5acd7..48bcb25 100644 --- a/src/EFCore.Jet/Query/Internal/JetQueryableMethodTranslatingExpressionVisitor.cs +++ b/src/EFCore.Jet/Query/Internal/JetQueryableMethodTranslatingExpressionVisitor.cs @@ -188,7 +188,8 @@ public class JetQueryableMethodTranslatingExpressionVisitor : RelationalQueryabl if (selectExpression.Offset == null && selectExpression.GroupBy.Count == 0 && selectExpression.Having == null - && selectExpression.Orderings.Count == 0) + && selectExpression.Orderings.Count == 0 + && selectExpression.Limit == null) { TableExpressionBase table; if (selectExpression.Tables.Count == 1) @@ -235,7 +236,8 @@ public class JetQueryableMethodTranslatingExpressionVisitor : RelationalQueryabl IsDistinct: false, GroupBy: [], Having: null, - Orderings: [] + Orderings: [], + Limit: null }) { if (selectExpression.Tables.Count > 1 && table is JoinExpressionBase joinExpressionBase) diff --git a/src/EFCore.Jet/Query/Sql/Internal/JetQuerySqlGenerator.cs b/src/EFCore.Jet/Query/Sql/Internal/JetQuerySqlGenerator.cs index 715d984..8a38eb3 100644 --- a/src/EFCore.Jet/Query/Sql/Internal/JetQuerySqlGenerator.cs +++ b/src/EFCore.Jet/Query/Sql/Internal/JetQuerySqlGenerator.cs @@ -869,11 +869,15 @@ namespace EntityFrameworkCore.Jet.Query.Sql.Internal && selectExpression.Projection.Count == 0) { Sql.Append("DELETE "); - GenerateTop(selectExpression); - Sql.Append($"{Dependencies.SqlGenerationHelper.DelimitIdentifier(deleteExpression.Table.Alias)}.*"); + if (selectExpression.Tables.Count > 1) + { + Sql.Append($"{Dependencies.SqlGenerationHelper.DelimitIdentifier(deleteExpression.Table.Alias)}.*"); + Sql.AppendLine(); + } - VisitJetTables(selectExpression.Tables, true, out _); + Sql.Append("FROM "); + VisitJetTables(selectExpression.Tables, false, out _); if (selectExpression.Predicate != null) { @@ -905,10 +909,10 @@ namespace EntityFrameworkCore.Jet.Query.Sql.Internal && selectExpression.Having == null && selectExpression.Orderings.Count == 0 && selectExpression.GroupBy.Count == 0 - && selectExpression.Projection.Count == 0) + && selectExpression.Projection.Count == 0 + && selectExpression.Limit == null) { Sql.Append("UPDATE "); - GenerateTop(selectExpression); VisitJetTables(selectExpression.Tables, false, out _); diff --git a/test/EFCore.Jet.FunctionalTests/BulkUpdates/ComplexTypeBulkUpdatesJetTest.cs b/test/EFCore.Jet.FunctionalTests/BulkUpdates/ComplexTypeBulkUpdatesJetTest.cs index b4e44b0..f5d1cbd 100644 --- a/test/EFCore.Jet.FunctionalTests/BulkUpdates/ComplexTypeBulkUpdatesJetTest.cs +++ b/test/EFCore.Jet.FunctionalTests/BulkUpdates/ComplexTypeBulkUpdatesJetTest.cs @@ -24,8 +24,7 @@ public class ComplexTypeBulkUpdatesJetTest : ComplexTypeBulkUpdatesTestBase< AssertSql( """ -DELETE `c`.* -FROM `Customer` AS `c` +DELETE FROM `Customer` AS `c` WHERE `c`.`Name` = 'Monty Elias' """); } diff --git a/test/EFCore.Jet.FunctionalTests/BulkUpdates/NonSharedModelBulkUpdatesJetTest.cs b/test/EFCore.Jet.FunctionalTests/BulkUpdates/NonSharedModelBulkUpdatesJetTest.cs index b15e043..238abb0 100644 --- a/test/EFCore.Jet.FunctionalTests/BulkUpdates/NonSharedModelBulkUpdatesJetTest.cs +++ b/test/EFCore.Jet.FunctionalTests/BulkUpdates/NonSharedModelBulkUpdatesJetTest.cs @@ -26,8 +26,7 @@ public class NonSharedModelBulkUpdatesJetTest : NonSharedModelBulkUpdatesTestBas AssertSql( """ -DELETE `o`.* -FROM `Owner` AS `o` +DELETE FROM `Owner` AS `o` """); } @@ -37,8 +36,7 @@ FROM `Owner` AS `o` AssertSql( """ -DELETE `o`.* -FROM `Owner` AS `o` +DELETE FROM `Owner` AS `o` """); } diff --git a/test/EFCore.Jet.FunctionalTests/BulkUpdates/NorthwindBulkUpdatesJetTest.cs b/test/EFCore.Jet.FunctionalTests/BulkUpdates/NorthwindBulkUpdatesJetTest.cs index ed864df..06f6b1b 100644 --- a/test/EFCore.Jet.FunctionalTests/BulkUpdates/NorthwindBulkUpdatesJetTest.cs +++ b/test/EFCore.Jet.FunctionalTests/BulkUpdates/NorthwindBulkUpdatesJetTest.cs @@ -28,8 +28,7 @@ public class NorthwindBulkUpdatesJetTest : NorthwindBulkUpdatesTestBase