Entity Framework Code First多对多关联表添加自增主键问题求助
解决方案
以下分两种场景实现,你可以根据自己的业务需求选择:
方案1:不新增中间实体,直接通过自定义迁移修改表结构
适合仅需要加自增主键,不需要插入重复的InspectionItemId+ViolationTypeId组合的场景
- 第一步:在包管理器控制台执行命令生成迁移文件:
Add-Migration ModifyInspectionItemViolationCategories - 第二步:修改生成的迁移文件的
Up和Down方法,手动写入表结构调整逻辑:
public override void Up() { // 删除原有的联合主键,该主键本身就是两列的联合唯一约束 DropPrimaryKey("dbo.InspectionItemViolationCategories"); // 新增自增主键列 AddColumn("dbo.InspectionItemViolationCategories", "Id", c => c.Int(nullable: false, identity: true)); // 将新增列设为新主键 AddPrimaryKey("dbo.InspectionItemViolationCategories", "Id"); } public override void Down() { // 回滚逻辑 DropPrimaryKey("dbo.InspectionItemViolationCategories"); DropColumn("dbo.InspectionItemViolationCategories", "Id"); AddPrimaryKey("dbo.InspectionItemViolationCategories", new[] { "InspectionItemId", "ViolationTypeId" }); }
- 第三步:执行命令应用修改到数据库:
Update-Database
注意:该方案存在限制,EF6的隐式多对多逻辑默认会认为两个外键的组合是唯一关联,如果你后续需要插入重复的关联组合,原生多对多操作会出现异常,这种场景建议直接用方案2。
方案2:显式定义中间实体(更推荐,长期维护更灵活)
适合需要插入重复关联组合,或者后续可能要给中间表加其他字段的场景
- 第一步:新增中间实体类:
public class InspectionItemViolationCategory { // 自增主键 public int Id { get; set; } public int InspectionItemId { get; set; } public int ViolationTypeId { get; set; } // 导航属性按需添加 public InspectionItem InspectionItem { get; set; } public ViolationType ViolationType { get; set; } }
- 第二步:删除原来的多对多配置,换成两个一对多的配置:
// 配置中间表主键自增 modelBuilder.Entity<InspectionItemViolationCategory>() .HasKey(x => x.Id) .Property(x => x.Id) .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); // 配置和InspectionItem的关联 modelBuilder.Entity<InspectionItemViolationCategory>() .HasRequired(x => x.InspectionItem) .WithMany(i => i.InspectionItemViolationCategories) .HasForeignKey(x => x.InspectionItemId); // 配置和ViolationType的关联 modelBuilder.Entity<InspectionItemViolationCategory>() .HasRequired(x => x.ViolationType) .WithMany() // 如果ViolationType需要反向导航属性,这里填入对应的集合属性名即可 .HasForeignKey(x => x.ViolationTypeId);
- 第三步:调整
InspectionItem实体的导航属性,把原来的ICollection<ViolationType> InspectionItemCategory替换为ICollection<InspectionItemViolationCategory> InspectionItemViolationCategories - 第四步:生成迁移并应用即可,EF会自动生成符合要求的表结构,默认不会加两列的联合唯一约束。
内容的提问来源于stack exchange,提问作者AbdulAleem
相关产品推荐
相关产品推荐

