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

EF6结合SQLite空主键报错:DB优先模式下如何实现主键自增

解决EF6+SQLite数据库优先模式下主键自增问题

嘿,作为SQLite新手刚迁移完数据库,遇到主键自增的问题很正常,我来一步步帮你搞定~

首先,我们得先把SQLite的表结构调整到位,再配合EF6的配置,就能实现自动自增了:

1. 调整SQLite表结构

你当前的ROISet表主键定义是ROISetID INTEGER DEFAULT NULL,虽然SQLite允许传入NULL让主键自动分配,但更规范的自增主键定义应该用AUTOINCREMENT关键字,这样能确保主键值严格递增且不会复用已删除的ID(适合大多数业务场景)。

修改后的建表语句如下:

CREATE TABLE ROISet ( 
    ROISetID INTEGER PRIMARY KEY AUTOINCREMENT, 
    ImageID INTEGER DEFAULT 0 NOT NULL, 
    Modified DATETIME NOT NULL DEFAULT (CURRENT_TIMESTAMP)
);

如果你不想用AUTOINCREMENT,只保留INTEGER PRIMARY KEY也能实现自增(SQLite会自动把该列设为ROWID的别名,插入NULL时自动生成值),但AUTOINCREMENT会强制使用更大的新ID,不会复用已删除的ID,看你业务需求选择。

2. 更新EF6数据库优先模型

表结构改好后,需要同步到EF的模型里:

  • 打开你的EDMX模型文件,右键点击空白处,选择从数据库更新模型,选中ROISet表完成更新。
  • 打开模型设计器,找到ROISet实体的ROISetID属性,在属性窗口里把StoreGeneratedPattern设置为Identity。这一步是告诉EF:这个字段的值由数据库自动生成,插入时不需要我们提供。
  • 如果你查看EF生成的实体类代码,应该会看到类似这样的特性(如果没有可以手动加上):
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int ROISetID { get; set; }
    

3. 插入数据的正确姿势

现在你创建ROISet实例时,完全不需要给ROISetID赋值,直接设置其他属性,然后保存到数据库即可:

using (var dbContext = new YourDbContext()) // 替换成你的实际DbContext类
{
    var newROISet = new ROISet
    {
        ImageID = 456, // 替换成你的实际值
        // Modified字段如果用了数据库默认值,这里可以不用设置,会自动取当前时间
        Modified = DateTime.Now // 也可以手动指定
    };

    dbContext.ROISets.Add(newROISet);
    dbContext.SaveChanges();

    // 保存后,EF会把数据库生成的自增值回写到实体对象里
    Console.WriteLine($"新生成的ROISetID: {newROISet.ROISetID}");
}

小提醒

  • 不要手动给ROISetID赋值(除非你有特殊业务需要手动指定ID),否则EF会把你传入的值发给数据库,可能破坏自增逻辑。
  • 如果你的表已经有数据,修改表结构时要注意数据迁移:SQLite的ALTER TABLE支持有限,直接修改主键列可能不行,建议先备份数据,重新创建表后再导入数据,或者用SQLite的工具辅助迁移。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 09:57:15