diff --git a/entity-framework/core/providers/sql-server/misc.md b/entity-framework/core/providers/sql-server/misc.md new file mode 100644 index 0000000000..d96653c9a7 --- /dev/null +++ b/entity-framework/core/providers/sql-server/misc.md @@ -0,0 +1,18 @@ +--- +title: Miscellaneous - Microsoft SQL Server Database Provider - EF Core +description: Miscellaneous for the Microsoft SQL Server database provider +author: roji +ms.date: 06/07/2021 +uid: core/providers/sql-server/misc +--- +# Miscellaneous notes for SQL Server + +## SaveChanges and database triggers + +Starting with EF Core 7.0, EF Core saves changes to the database with significantly optimized SQL; unfortunately, this technique is not supported on SQL Server if the target table has database triggers. For more information on this SQL Server limitation, see the documentation on the [OUTPUT clause](/sql/t-sql/queries/output-clause-transact-sql). + +You can let EF Core know that the target table has a trigger; doing so will revert to the previous, less efficient technique. This can be done by configuring the corresponding entity type as follows: + +[!code-csharp[Main](../../../../samples/core/SqlServer/Misc/TriggersContext.cs?name=TriggerConfiguration&highlight=4)] + +Note that doing this doesn't actually make EF Core create or manage the trigger in any way - it currently only informs EF Core that triggers are present on the table. As a result, any trigger name can be used. diff --git a/entity-framework/core/what-is-new/ef-core-7.0/breaking-changes.md b/entity-framework/core/what-is-new/ef-core-7.0/breaking-changes.md index 0800ed2fb0..0235ea2ad4 100644 --- a/entity-framework/core/what-is-new/ef-core-7.0/breaking-changes.md +++ b/entity-framework/core/what-is-new/ef-core-7.0/breaking-changes.md @@ -9,3 +9,37 @@ uid: core/what-is-new/ef-core-7.0/breaking-changes # Breaking changes in EF Core 7.0 API and behavior changes have the potential to break existing applications updating to EF Core 7.0.0 will be documented here. + +## Summary + +| **Breaking change** | **Impact** | +|:------------------------------------------------------------------------------------------------------------ | ----------- | +| [SQL Server tables with triggers now require special EF Core configuration](#sqlserver-tables-with-triggers) | High | + +## High-impact changes + + + +### SQL Server tables with triggers now require special EF Core configuration + +[Tracking Issue #27372](https://github.com/dotnet/efcore/issues/27372) + +#### Old behavior + +Previous versions of the SQL Server saved changes via a less efficient technique which always worked. + +#### New behavior + +By default, EF Core now saves changes via a significantly more efficient technique; unfortunately, this technique is not supported on SQL Server if the target table has database triggers. + +#### Why + +The performance improvements linked to the new method are significant enough that it's important to bring them to users by default. At the same time, we estimate usage of database triggers in EF Core applications to be low enough that the negative breaking change consequences are outweighed by the performance gain. + +#### Mitigations + +You can let EF Core know that the target table has a trigger; doing so will revert to the previous, less efficient technique. This can be done by configuring the corresponding entity type as follows: + +[!code-csharp[Main](../../../../samples/core/SqlServer/Misc/TriggersContext.cs?name=TriggerConfiguration&highlight=4)] + +Note that doing this doesn't actually make EF Core create or manage the trigger in any way - it currently only informs EF Core that triggers are present on the table. As a result, any trigger name can be used. diff --git a/entity-framework/toc.yml b/entity-framework/toc.yml index b912c52bed..5ee3bb6e8a 100644 --- a/entity-framework/toc.yml +++ b/entity-framework/toc.yml @@ -357,6 +357,8 @@ href: core/providers/sql-server/spatial.md - name: Specify Azure SQL Database options href: core/providers/sql-server/azure-sql-database.md + - name: Miscellaneous + href: core/providers/sql-server/misc.md - name: SQLite items: - name: Overview diff --git a/samples/core/SqlServer/Misc/Blog.cs b/samples/core/SqlServer/Misc/Blog.cs new file mode 100644 index 0000000000..a7c92dae97 --- /dev/null +++ b/samples/core/SqlServer/Misc/Blog.cs @@ -0,0 +1,7 @@ +namespace SqlServer.Faq; + +public class Blog +{ + public int BlogId { get; set; } + public string Url { get; set; } +} diff --git a/samples/core/SqlServer/Misc/TriggersContext.cs b/samples/core/SqlServer/Misc/TriggersContext.cs new file mode 100644 index 0000000000..ad6977439f --- /dev/null +++ b/samples/core/SqlServer/Misc/TriggersContext.cs @@ -0,0 +1,17 @@ + +using Microsoft.EntityFrameworkCore; + +namespace SqlServer.Faq; + +public class TriggersContext : DbContext +{ + public DbSet Blogs { get; set; } + + #region TriggerConfiguration + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + modelBuilder.Entity() + .ToTable(tb => tb.HasTrigger("SomeTrigger")); + } + #endregion +} diff --git a/samples/core/SqlServer/SqlServer.csproj b/samples/core/SqlServer/SqlServer.csproj index cde0db78e1..0f9ddaa6fc 100644 --- a/samples/core/SqlServer/SqlServer.csproj +++ b/samples/core/SqlServer/SqlServer.csproj @@ -6,7 +6,7 @@ - +