EF Core 7搭配SQL Data Sync时增删改操作报错求助
我有一个从.NET Core 3.1逐步升级到6.0的API,运行正常。升级到EF Core 7后,查询请求可正常执行,但执行插入、更新或删除操作时触发报错:
无法保存更改,因为目标表存在数据库触发器。请相应配置实体类型。
如果DML语句包含不带INTO子句的OUTPUT子句,则该语句的目标表'table_name'不能有任何启用的触发器。
排查后确认数据库无自定义触发器,仅启用了Microsoft SQL Data Sync服务用于本地数据库与Azure数据库同步,且必须保留该同步功能,无法沿用EF Core 6时忽略同步逻辑的配置,需要找到EF Core 7下让写入操作兼容同步触发逻辑的方法。
附EF Core实体配置代码:
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; namespace Configurations { class MainTokenConfiguration : IEntityTypeConfiguration<MainToken> { public void Configure(EntityTypeBuilder<MainToken> builder) { builder.ToTable("main_token"); builder.Property(e => e.Id) .HasMaxLength(100) .IsUnicode(false) .HasColumnName("id") .HasDefaultValueSql("(newid())"); builder.Property(e => e.Token) .HasMaxLength(5000) .IsUnicode(false) .HasColumnName("token"); builder.Property(e => e.CreatedBy) .HasMaxLength(500) .HasColumnName("created_by"); builder.Property(e => e.CreationDate) .HasColumnType("datetime") .HasColumnName("creation_date"); builder.Property(e => e.Email) .IsRequired() .HasMaxLength(250) .IsUnicode(false) .HasColumnName("email"); builder.Property(e => e.ExpirationDate) .HasColumnType("datetime") .HasColumnName("expiration_date"); } } }
EF Core 7对带触发器的表写入操作默认行为有变更,针对SQL Data Sync自动创建的系统触发器,可通过以下两种方式解决:
1. 全局禁用OUTPUT子句(适用于所有实体)
在DbContext的OnConfiguring方法中配置SQL Server选项,禁用EF Core自动生成OUTPUT子句:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { optionsBuilder.UseSqlServer( "你的数据库连接字符串", options => options.UseOutputClause(false)); }
该设置会让EF Core在执行写入操作时不生成OUTPUT子句,避开SQL Server关于触发器与OUTPUT子句的限制。
2. 针对单个实体配置(仅影响指定表)
如果不想全局禁用,可在实体配置类中为指定实体添加禁用OUTPUT子句的配置:
public void Configure(EntityTypeBuilder<MainToken> builder) { // 保留原有实体配置 builder.ToTable("main_token"); // ... 其他属性配置 // 添加禁用OUTPUT子句的配置 builder.UseSqlOutputClause(false); }
原理说明
SQL Data Sync会自动在同步表上创建系统触发器,EF Core 7默认会在写入操作中生成不带INTO子句的OUTPUT子句,而SQL Server不允许这类语句作用在有触发器的表上。通过禁用OUTPUT子句的生成,即可兼容Data Sync的同步功能,同时解决写入报错问题。
内容的提问来源于stack exchange,提问作者Joshue

