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
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -368,3 +368,5 @@ FodyWeavers.xsd

# Rider
.idea/

.DS_Store
12 changes: 9 additions & 3 deletions entity-framework/core/extensions/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -286,15 +286,21 @@ This package focuses on adding data masking support for SQL Server to EF Core. F

[GitHub repository](https://github.com/sander1095/EntityFrameworkCore.Extensions.SqlServer.DataMasking) | [NuGet](https://www.nuget.org/packages/SanderTenBrinke.EntityFrameworkCore.Extensions.SqlServer.DataMasking)

### EFCommenter

All xml summaries of entities, properties, and enums will be added as comments on the corresponding database tables and columns. For EF Core: 9.

[GitHub repository](https://github.com/roohial57/DotNetComponent_EFCommenter) | [NuGet](https://www.nuget.org/packages/EFCommenter)

## API Integrations

These packages are designed to integrate directly with EF Core to expose various APIs.

### .NET Aspire
### Aspire

Enhance the local development experience by simplifying the management of your cloud-native app's configuration and interconnections. For EF Core: 8.
Enhance the local development experience by simplifying the management of your cloud-native app's configuration and interconnections. For EF Core: 8-10.

[Website](/dotnet/aspire/get-started/aspire-overview) | [GitHub repository](https://github.com/dotnet/aspire) | [NuGet](https://www.nuget.org/profiles/aspire)
[Website](https://aspire.dev) | [GitHub repository](https://github.com/dotnet/aspire) | [NuGet](https://www.nuget.org/profiles/aspire)

### HotChocolate

Expand Down
2 changes: 1 addition & 1 deletion entity-framework/core/providers/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ Entity Framework Core can access many different databases through plug-in librar
| [Npgsql.EntityFrameworkCore.PostgreSQL](https://www.nuget.org/packages/Npgsql.EntityFrameworkCore.PostgreSQL) | PostgreSQL | [Npgsql Development Team](https://github.com/npgsql) | | 8, 9 | [docs](https://www.npgsql.org/efcore/index.html) |
| [Pomelo.EntityFrameworkCore.MySql](https://www.nuget.org/packages/Pomelo.EntityFrameworkCore.MySql) | MySQL, MariaDB | [Pomelo Foundation Project](https://github.com/PomeloFoundation) | | 8, 9 | [readme](https://github.com/PomeloFoundation/Pomelo.EntityFrameworkCore.MySql/blob/master/README.md) |
| [MySql.EntityFrameworkCore](https://www.nuget.org/packages/MySql.EntityFrameworkCore) | MySQL | [MySQL project](https://dev.mysql.com) (Oracle) | | 8, 9 | [docs](https://dev.mysql.com/doc/connector-net/en/connector-net-entityframework-core.html) |
| [Oracle.EntityFrameworkCore](https://www.nuget.org/packages/Oracle.EntityFrameworkCore/) | Oracle DB 11.2 onwards | [Oracle](https://www.oracle.com/technetwork/topics/dotnet/) | | 8, 9 | [website](https://www.oracle.com/technetwork/topics/dotnet/) |
| [Oracle.EntityFrameworkCore](https://www.nuget.org/packages/Oracle.EntityFrameworkCore/) | Oracle DB 19c onwards | [Oracle](https://www.oracle.com/technetwork/topics/dotnet/) | | 8, 9, 10 | [docs](https://docs.oracle.com/en/database/oracle/oracle-database/26/odpnt/ODPEFCore.html) |
| [MongoDB.EntityFrameworkCore](https://www.nuget.org/packages/MongoDB.EntityFrameworkCore/) | MongoDB | [MongoDB](https://www.mongodb.com/) | | 8 | [docs](https://www.mongodb.com/docs/entity-framework/current/) |
| [Couchbase.EntityFrameworkCore](https://www.nuget.org/packages/Couchbase.EntityFrameworkCore) | Couchbase | [Couchbase](https://github.com/couchbaselabs/couchbase-efcore-provider) | | 8, 9 | [docs](https://docs.couchbase.com/efcore-provider/current/start-using-efcore-provider.html) |
| [Devart.Data.MySql.EFCore](https://www.nuget.org/packages/Devart.Data.MySql.EFCore/) | MySQL 5 onwards | [DevArt](https://www.devart.com/dotconnect/mysql/) | Paid | 8, 9 | [docs](https://docs.devart.com/dotconnect/mysql/GettingStarted.html) |
Expand Down
62 changes: 43 additions & 19 deletions entity-framework/core/providers/sql-server/misc.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,22 +33,46 @@ Use [HasPerformanceLevelSql](/dotnet/api/Microsoft.EntityFrameworkCore.SqlServer
> [!TIP]
> You can find all the supported values in the [ALTER DATABASE documentation](/sql/t-sql/statements/alter-database-transact-sql?view=azuresqldb-current&preserve-view=true).

## SaveChanges, database triggers and unsupported computed columns

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, or certain kinds of computed columns. For more information on this SQL Server limitation, see the documentation on the [OUTPUT clause](/sql/t-sql/queries/output-clause-transact-sql#remarks).

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, and this can also be used if an unsupported computed column is in use (regardless of triggers).

If most or all of your tables have triggers, you can opt out of using the newer, efficient technique for all your model's tables by using the following [model building convention](xref:core/modeling/bulk-configuration#conventions):

[!code-csharp[Main](../../../../samples/core/SqlServer/Misc/TriggersContext.cs?name=BlankTriggerAddingConvention)]

Use the convention on your `DbContext` by overriding `ConfigureConventions`:

[!code-csharp[Main](../../../../samples/core/SqlServer/Misc/TriggersContext.cs?name=ConfigureConventions)]

This effectively calls `HasTrigger` on all your model's tables, instead of you having to do it manually for each and every table.
## SaveChanges, triggers and the OUTPUT clause

When EF Core saves changes to the database, it does so with an optimized technique using the T-SQL [OUTPUT clause](/sql/t-sql/queries/output-clause-transact-sql#remarks). Unfortunately, the OUTPUT clause has some limitations; it notably cannot be used with tables that have triggers, for example.

If you run into a limitation related to the use of the OUTPUT clause, you can disable it on a specific table via <xref:Microsoft.EntityFrameworkCore.SqlServerEntityTypeExtensions.UseSqlOutputClause*>:

```c#
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Blog>()
.ToTable(tb => tb.UseSqlOutputClause(false));
}
```

Doing this will make EF switch to an older, less efficient technique for updating the table.

If most or all of your tables have triggers, you can configure this for all your model's tables by using the following [model building convention](xref:core/modeling/bulk-configuration#conventions):

```c#
public class NoOutputClauseConvention : IModelFinalizingConvention
{
public virtual void ProcessModelFinalizing(
IConventionModelBuilder modelBuilder,
IConventionContext<IConventionModelBuilder> context)
{
foreach (var entityType in modelBuilder.Metadata.GetEntityTypes())
{
var table = StoreObjectIdentifier.Create(entityType, StoreObjectType.Table);
if (table is not null)
{
entityType.Builder.UseSqlOutputClause(false);
}

foreach (var fragment in entityType.GetMappingFragments(StoreObjectType.Table))
{
entityType.Builder.UseSqlOutputClause(false, fragment.StoreObject);
}
}
}
}
```

This effectively calls <xref:Microsoft.EntityFrameworkCore.SqlServerEntityTypeExtensions.UseSqlOutputClause*> on all your model's tables, instead of you having to do it manually for each and every table.
52 changes: 52 additions & 0 deletions entity-framework/core/providers/sqlite/misc.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
---
title: Miscellaneous - SQLite Database Provider - EF Core
description: Miscellaneous information for the SQLite database provider
author: roji
ms.date: 11/27/2025
uid: core/providers/sqlite/misc
---
# Miscellaneous notes for SQLite

## SaveChanges and the RETURNING clause

When EF Core saves changes to the database, it does so with an optimized technique using the SQL [RETURNING clause](https://sqlite.org/lang_returning.html). Unfortunately, the RETURNING clause has some limitations; it cannot be used with virtual tables or tables with certain trigger types, for example.

If you run into a limitation related to the use of the RETURNING clause, you can disable it on a specific table via <xref:Microsoft.EntityFrameworkCore.SqliteEntityTypeExtensions.UseSqlReturningClause*>:

```c#
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Blog>()
.ToTable(tb => tb.UseSqlReturningClause(false));
}
```

Doing this will make EF switch to an older, less efficient technique for updating the table.

If most or all of your tables have triggers, you can configure this for all your model's tables by using the following [model building convention](xref:core/modeling/bulk-configuration#conventions):

```c#
public class NoOutputClauseConvention : IModelFinalizingConvention
{
public virtual void ProcessModelFinalizing(
IConventionModelBuilder modelBuilder,
IConventionContext<IConventionModelBuilder> context)
{
foreach (var entityType in modelBuilder.Metadata.GetEntityTypes())
{
var table = StoreObjectIdentifier.Create(entityType, StoreObjectType.Table);
if (table is not null)
{
entityType.Builder.UseSqlReturningClause(false);
}

foreach (var fragment in entityType.GetMappingFragments(StoreObjectType.Table))
{
entityType.Builder.UseSqlReturningClause(false, fragment.StoreObject);
}
}
}
}
```

This effectively calls <xref:Microsoft.EntityFrameworkCore.SqliteEntityTypeExtensions.UseSqlReturningClause*> on all your model's tables, instead of you having to do it manually for each and every table.
26 changes: 13 additions & 13 deletions entity-framework/core/what-is-new/ef-core-7.0/breaking-changes.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,9 @@ The performance improvements linked to the new method are significant enough tha

#### Mitigations

Starting with EF Core 8.0, the use or not of the "OUTPUT" clause can be configured explicitly. For example:
In EF7 or later, if the target table has a trigger, then you can let EF Core know this, and EF will revert to the previous, less efficient technique. This can be done by configuring the corresponding entity type as follows:

##### [EF 8+](#tab/data-annotations)

```csharp
protected override void OnModelCreating(ModelBuilder modelBuilder)
Expand All @@ -141,21 +143,19 @@ protected override void OnModelCreating(ModelBuilder modelBuilder)
}
```

In EF7 or later, If the target table has a trigger, then you can let EF Core know this, and EF 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. Specifying a trigger can be used to revert the old behavior _even if there isn't actually a trigger in the table_.
##### [EF 7](#tab/fluent-api)

If most or all of your tables have triggers, you can opt out of using the newer, efficient technique for all your model's tables by using the following model building convention:

[!code-csharp[Main](../../../../samples/core/SqlServer/Misc/TriggersContext.cs?name=BlankTriggerAddingConvention)]

Use the convention on your `DbContext` by overriding `ConfigureConventions`:
```csharp
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Blog>()
.ToTable(tb => tb.HasTrigger("SomeTrigger"));
}
```

[!code-csharp[Main](../../../../samples/core/SqlServer/Misc/TriggersContext.cs?name=ConfigureConventions)]
---

This effectively calls `HasTrigger` on all your model's tables, instead of you having to do it manually for each and every table.
For more information, including on how to configure this for all your tables, see the [SQL Server documentation](xref:core/providers/sql-server/misc#savechanges-triggers-and-the-output-clause).

<a name="sqlitetriggers"></a>

Expand Down
2 changes: 2 additions & 0 deletions entity-framework/core/what-is-new/ef-core-8.0/whatsnew.md
Original file line number Diff line number Diff line change
Expand Up @@ -2633,6 +2633,8 @@ Or to opt-out of `RETURNING` when using the SQLite provider:
modelBuilder.Entity<Customer>().ToTable(tb => tb.UseSqlReturningClause(false));
```

See the [SQL Server](xref:core/providers/sql-server/misc#savechanges-triggers-and-the-output-clause) and [SQLite](xref:core/providers/sqlite/misc#savechanges-and-the-returning-clause) documentation pages for more details.

## Other minor changes

In addition to the enhancements described above, there have been many smaller changes made to EF8. This includes:
Expand Down
2 changes: 2 additions & 0 deletions entity-framework/toc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,8 @@
- name: Spatial data
displayName: GIS
href: core/providers/sqlite/spatial.md
- name: Miscellaneous
href: core/providers/sqlite/misc.md
- name: Microsoft.Data.Sqlite >>
href: /dotnet/standard/data/sqlite/
- name: Azure Cosmos DB
Expand Down
Binary file added samples/core/.DS_Store
Binary file not shown.
Binary file added samples/core/Miscellaneous/.DS_Store
Binary file not shown.
7 changes: 0 additions & 7 deletions samples/core/SqlServer/Misc/Blog.cs

This file was deleted.

58 changes: 0 additions & 58 deletions samples/core/SqlServer/Misc/TriggersContext.cs

This file was deleted.

Loading