You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET 8中EF插入ProcessingFlags表触发Identity列插入异常

解决方法

方案1:移除Id列的IDENTITY属性

既然需要手动插入枚举值作为Id,直接去掉数据库中ProcessingFlags表Id列的IDENTITY(1,1)属性:

  1. 在ProcessingFlagsConfiguration中配置Id为手动赋值:
public class ProcessingFlagsConfiguration : IEntityTypeConfiguration<JobRunning>
{
    public void Configure(EntityTypeBuilder<JobRunning> builder)
    {
        builder.HasKey(e => e.Id);
        // 明确指定Id由用户提供,而非数据库生成
        builder.Property(e => e.Id).ValueGeneratedNever();
    }
}
  1. 生成新的迁移:
Add-Migration RemoveProcessingFlagsIdIdentity
  1. 执行迁移更新数据库:
Update-Database

这样数据库的Id列不再是自增列,外部库设置的枚举值就能正常插入。

方案2:保留IDENTITY属性,插入时临时开启IDENTITY_INSERT

如果必须保留Id列的IDENTITY属性,可以通过EF Core的拦截器在插入JobRunning实体时自动开启IDENTITY_INSERT:

  1. 创建一个拦截器类:
public class ProcessingFlagsIdentityInsertInterceptor : SaveChangesInterceptor
{
    public override InterceptionResult<int> SavingChanges(DbContextEventData eventData, InterceptionResult<int> result)
    {
        var context = eventData.Context;
        if (context == null) return result;

        // 检查是否有JobRunning实体需要插入
        var pendingInserts = context.ChangeTracker.Entries<JobRunning>()
            .Where(e => e.State == EntityState.Added);

        if (pendingInserts.Any())
        {
            // 开启IDENTITY_INSERT
            context.Database.ExecuteSqlRaw("SET IDENTITY_INSERT ProcessingFlags ON");
            // 执行保存后关闭IDENTITY_INSERT
            context.SaveChangesCompleted += (s, e) =>
            {
                context.Database.ExecuteSqlRaw("SET IDENTITY_INSERT ProcessingFlags OFF");
            };
        }

        return result;
    }
}
  1. 在DbContext中注册拦截器:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
    optionsBuilder.AddInterceptors(new ProcessingFlagsIdentityInsertInterceptor());
}
  1. 无需修改现有迁移,直接运行程序即可。外部库设置的枚举Id会被正常插入,插入完成后IDENTITY_INSERT自动关闭。

为什么ValueGeneratedOnAdd无效?

ValueGeneratedOnAdd的作用是告诉EF:当实体的Id为默认值(比如int类型的0)时,由数据库生成值。但外部库会主动给Id赋值为枚举值(非默认值),此时EF会认为需要将这个值插入到数据库,而数据库的IDENTITY列不允许手动插入值(除非IDENTITY_INSERT开启),所以依然会报错。

内容的提问来源于stack exchange,提问作者Diego Perez

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 23:16:02