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

EF Core Code First新增数据报Id重复 如何设置自增主键起始值

问题根因

主键重复报错的核心原因是:你手动向Destinations表插入存量数据时,没有同步更新Id列绑定的自增序列当前值,序列生成的下一个Id小于表内已存在的最大主键,导致EF Core调用SaveChangesAsync插入新记录时,拿到重复Id触发主键唯一约束冲突。
你实体类中对Id配置的[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]特性本身没有问题,不需要修改实体定义和业务层的Create方法逻辑。

实现方案

所有方案均不会删除或修改表现有存量数据,满足不丢失历史数据的要求。

1. 先确认表绑定的自增序列名称

PostgreSQL中EF Core Code First生成的int类型自增主键,默认绑定的序列名格式为"表名_列名_seq",你当前库中对应的序列就是public."Destinations_Id_seq",可以执行以下SQL确认:

SELECT column_default 
FROM information_schema.columns 
WHERE table_name = 'Destinations' AND column_name = 'Id';

返回结果格式为nextval('"Destinations_Id_seq"'::regclass)即可确认序列名称正确。

2. 分环境设置自增起始值

自增序列调用nextval时会先累加1再返回值,因此设置序列重启值时,需要比你预期的第一条新记录Id小1:

  • 本地环境新Id从301开始,序列重启值设为300
  • 开发环境新Id从201开始,序列重启值设为200
  • 生产环境新Id从241开始,序列重启值设为240

你可以根据项目实际情况选以下任意一种方式配置:

方式一:代码层适配多环境(推荐长期维护使用)

通过配置文件+EF Core模型配置实现环境自动适配,后续发布无需手动操作数据库:

  1. 在不同环境的配置文件appsettings.{环境名}.json中加入对应配置项
    // 本地appsettings.Development.json示例
    {
      "DbSequence": {
        "DestinationIdRestartValue": 300
      }
    }
    
    开发环境对应值设为200,生产环境对应值设为240即可。
  2. 在DbContext中注入配置,重写OnModelCreating方法指定自增列起始值
    private readonly IConfiguration _configuration;
    // 构造函数注入IConfiguration
    public CatalogDbContext(DbContextOptions<CatalogDbContext> options, IConfiguration configuration) : base(options)
    {
        _configuration = configuration;
    }
    
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        var restartValue = _configuration.GetValue<int>("DbSequence:DestinationIdRestartValue");
        modelBuilder.Entity<Destination>()
            .Property(d => d.Id)
            // 第一个参数为自增起始值,第二个参数为自增步长固定为1
            .UseIdentityColumn(restartValue + 1, 1);
        
        base.OnModelCreating(modelBuilder);
    }
    
  3. 因为表已经存在,首次上线前需要在对应环境执行一次序列更新SQL,后续EF Core迁移会自动维护序列值,无需重复操作。

方式二:手动执行SQL快速修复(适合存量库紧急修复)

直接连接对应环境的数据库,执行对应环境的序列调整SQL即可,执行后立即生效:

-- 本地环境执行
ALTER SEQUENCE "Destinations_Id_seq" RESTART WITH 300;

-- 开发环境执行
ALTER SEQUENCE "Destinations_Id_seq" RESTART WITH 200;

-- 生产环境执行
ALTER SEQUENCE "Destinations_Id_seq" RESTART WITH 240;

3. 配置验证

执行完配置后,可以通过以下SQL查询序列下一个返回值,确认配置生效:

SELECT nextval('"Destinations_Id_seq"');

如果返回值+1等于你预期的第一条新记录Id,说明配置正确,后续新增Destination记录时会按设定值自动递增,不会再出现主键重复错误。

内容的提问来源于stack exchange,提问作者hanushi-thana

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.20 16:15:48