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
相关产品推荐
相关产品推荐

