EF模型创建SQL Server数据库外键级联错误配置方法
问题原因
EF Core 默认会为不可空外键关联的关系自动配置级联删除行为。BilanPatrimonial实体同时包含两个指向EtatCivil表的不可空外键字段EtatCivilMonsieurID、EtatCivilMadameID,会被EF Core识别为必填关系,自动开启级联删除。SQL Server不允许单表存在多条指向同一目标表的级联删除路径,因此抛出多重级联访问路径的建库错误。
另外实体上EtatCivilMonsieurID字段的特性配置存在错误:BilanPatrimonial的主键已经是ID属性,不需要给外键字段加[Key]标记,且ForeignKey指定的导航属性名不匹配,这是EF Core额外生成带1后缀的异常外键EtatCivilMonsieurID1的直接原因。
修复步骤
1. 修正实体类特性配置
移除EtatCivilMonsieurID上错误的[Key]标记,修正ForeignKey关联的导航属性名,同时为第二个外键补充正确的关联标记:
public class BilanPatrimonial { public int ID { get; set; } [ForeignKey(nameof(EtatCivilMonsieur))] public int EtatCivilMonsieurID { get; set; } public EtatCivil EtatCivilMonsieur { get; set; } [ForeignKey(nameof(EtatCivilMadame))] public int EtatCivilMadameID { get; set; } public EtatCivil EtatCivilMadame { get; set; } }
2. 手动配置关系的删除行为
在OnModelCreating方法中,为两个指向EtatCivil的关联关系手动配置删除规则为NoAction,避免生成多重级联路径:
protected override void OnModelCreating(ModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); // 原有表映射配置保留 modelBuilder.Entity<Annonce>().ToTable("Annonces"); modelBuilder.Entity<HonorairesAChargeDe>().ToTable("HonorairesAChargeDe"); modelBuilder.Entity<TypeChauffage>().ToTable("TypesChauffage"); modelBuilder.Entity<TypeCuisine>().ToTable("TypesCuisine"); modelBuilder.Entity<Favori>().ToTable("Favoris"); modelBuilder.Entity<Agenda>().ToTable("Agendas"); modelBuilder.Entity<Evenement>().ToTable("Evenements"); modelBuilder.Entity<Offre>().ToTable("Offres"); modelBuilder.Entity<BilanPatrimonial>().ToTable("BilansPatrimoniaux"); modelBuilder.Entity<EtatCivil>().ToTable("EtatCivils"); // 新增外键级联行为配置 modelBuilder.Entity<BilanPatrimonial>() .HasOne(b => b.EtatCivilMonsieur) .WithMany() .HasForeignKey(b => b.EtatCivilMonsieurID) .OnDelete(DeleteBehavior.NoAction); modelBuilder.Entity<BilanPatrimonial>() .HasOne(b => b.EtatCivilMadame) .WithMany() .HasForeignKey(b => b.EtatCivilMadameID) .OnDelete(DeleteBehavior.NoAction); }
补充说明
- 配置
DeleteBehavior.NoAction后,删除EtatCivil记录前需要先手动处理关联的BilanPatrimonial数据,否则数据库会抛出外键约束冲突错误。如果业务允许配偶信息为空,也可以将两个外键字段改为可空类型int?,可空外键默认级联行为为SetNull,不会触发多重级联路径错误。 - 重新生成迁移前建议删除之前生成的错误迁移文件,避免残留的错误外键配置影响数据库创建。
内容的提问来源于stack exchange,提问作者SylvainKrier
相关产品推荐
相关产品推荐

