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

如何在EF Core Code First模式下将主键从GUID改为int?

EF Core Code First下将GUID主键改为Int的实践方案(千万级数据场景)

针对SQL Server中10-20百万条数据的遗留库,直接修改主键类型风险极高,必须分阶段平滑过渡,避免锁表和业务中断,以下是可落地的步骤:

1. 准备阶段:新增Int列并填充数据

  • 在实体类中添加可空Int类型的临时主键列,比如NewId:
    public Guid Id { get; set; } // 原GUID主键
    public int? NewId { get; set; } // 新增临时列
    
  • 生成EF Core迁移并执行,在数据库中新增NewId列,设置为自增列(SQL Server会自动为现有百万条数据填充连续的Int值)。这一步务必在业务低峰期操作,避免IO过载。

2. 双写阶段:同步新老主键数据

  • 修改业务代码,新增实体时同时维护原GUID主键和NewId(依赖数据库自增的话无需手动赋值);更新操作不修改NewId,仅保留原有逻辑的同时确保NewId值稳定。
  • 这一阶段持续运行1-2个业务周期,确保所有新数据都有NewId,同时验证读写逻辑无异常。

3. 关联表适配:同步外键数据

  • 若当前表存在外键关联其他表,给每个关联表新增对应的NewXXXId列(比如主表是User,关联表Order新增NewUserId)。
  • 分批更新关联表的新外键列,每次更新1000条数据,避免长时间锁表:
    WHILE EXISTS(SELECT 1 FROM Order WHERE NewUserId IS NULL)
    BEGIN
        UPDATE TOP(1000) o
        SET o.NewUserId = u.NewId
        FROM Order o
        JOIN User u ON o.UserId = u.Id
        WHERE o.NewUserId IS NULL
    END
    
  • 给所有NewId列添加唯一非聚集索引,确保数据唯一性,为后续切换主键做准备。

4. 切换主键:替换GUID为Int

  • 先将NewId列改为非空(此时所有数据已填充值),生成并执行迁移:
    public int NewId { get; set; } // 去掉可空标记
    
  • 修改实体类的主键配置,移除原GUID列的[Key]特性,给NewId加上[Key]:
    // [Key] 注释掉原主键标记
    public Guid Id { get; set; }
    [Key]
    public int NewId { get; set; }
    
  • 手动修改EF Core生成的迁移文件,避免自动生成的高风险操作:
    // 先删除原主键约束
    migrationBuilder.DropPrimaryKey(
        name: "PK_YourTableName",
        table: "YourTableName");
    
    // 添加新主键约束
    migrationBuilder.AddPrimaryKey(
        name: "PK_YourTableName",
        table: "YourTableName",
        column: "NewId");
    
  • 在低峰期执行该迁移,期间监控数据库锁表情况。

5. 清理阶段:移除冗余数据

  • 确认所有业务代码已完全切换到使用NewId作为主键后,逐步删除原GUID主键列、关联表的旧外键列,以及对应的冗余索引。
  • 清理操作同样分批执行,避免影响业务。

关键注意事项

  • 所有操作前必须全量备份数据库,防止数据丢失。
  • 批量更新、主键切换等操作必须在业务低峰期执行,必要时可短暂只读降级。
  • 若为分布式系统,需改用全局唯一的Int生成策略(如雪花算法)替代自增列,避免主键冲突。

内容的提问来源于stack exchange,提问作者kaushal sharma

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 09:00:00