EF Core迁移InsertData顺序异常:种子数据插入引发外键错误
解决EF Core迁移种子数据插入顺序问题
方法1:按依赖顺序配置HasData
EF Core的HasData会尝试根据外键依赖自动排序,但遇到复合主键关联这类特殊场景时,显式按依赖顺序配置模型种子数据更可靠:
- 先配置被依赖表(表A、表B)的
HasData,最后配置依赖表(表C)的HasData - 示例代码:
// 先配置表A种子数据 modelBuilder.Entity<TableA>().HasData( new TableA { Id = 1, Name = "A1" }, new TableA { Id = 2, Name = "A2" } ); // 再配置表B种子数据 modelBuilder.Entity<TableB>().HasData( new TableB { Id = 1, Name = "B1" }, new TableB { Id = 2, Name = "B2" } ); // 最后配置依赖A、B的表C种子数据 modelBuilder.Entity<TableC>().HasData( new TableC { TableAId = 1, TableBId = 1 }, new TableC { TableAId = 1, TableBId = 2 } );
重新生成迁移时,EF Core会按配置顺序生成插入语句。
方法2:手动编写迁移的Up方法逻辑
如果自动排序仍失效,直接删除迁移类中自动生成的InsertData语句,手动用Sql方法按顺序编写插入逻辑:
protected override void Up(MigrationBuilder migrationBuilder) { // 先插入表A migrationBuilder.Sql("INSERT INTO TableA (Id, Name) VALUES (1, 'A1'), (2, 'A2');"); // 再插入表B migrationBuilder.Sql("INSERT INTO TableB (Id, Name) VALUES (1, 'B1'), (2, 'B2');"); // 最后插入表C migrationBuilder.Sql("INSERT INTO TableC (TableAId, TableBId) VALUES (1,1), (1,2);"); }
方法3:使用PostDeployment脚本(适合大量固定数据)
如果种子数据量极大,推荐创建PostDeployment脚本:
- 在项目中添加
.sql文件,设置其生成操作为PostDeploy - 脚本内按依赖顺序编写所有插入语句:
-- PostDeployment.sql INSERT INTO TableA (Id, Name) VALUES (1, 'A1'), (2, 'A2'); INSERT INTO TableB (Id, Name) VALUES (1, 'B1'), (2, 'B2'); INSERT INTO TableC (TableAId, TableBId) VALUES (1,1), (1,2);
EF Core会在迁移完成后自动执行该脚本,彻底避免顺序问题。
内容的提问来源于stack exchange,提问作者Stephan Pich
相关产品推荐
相关产品推荐

