entity framework代码首先:循环或多个级联路径

我有一个Booking类,它有一个预订联系人(一个Person )和一组导航属性( People ),它们通过连接表链接到另一组Person的导航属性( Bookings )。 如何生成Booking表,并为预订联系人关系启用了级联删除? 当我将它从流畅的API代码中删除时(启用了级联删除的默认设置),我从迁移中收到以下错误消息:

在’BookingPeople’表上引入FOREIGN KEY约束’FK_dbo.BookingPeople_dbo.People_PersonID’可能会导致循环或多个级联路径。 指定ON DELETE NO ACTION或ON UPDATE NO ACTION,或修改其他FOREIGN KEY约束。

无法创建约束或索引。 查看以前的错误。

  modelBuilder.Entity() .HasMany(s => s.aBookings) .WithRequired(s => s.Contact) .HasForeignKey(s => s.ContactId); modelBuilder.Entity() .HasMany(t => t.People) .WithMany(t => t.Bookings) .Map(m => { m.ToTable("BookingPeople"); m.MapLeftKey("BookingID"); m.MapRightKey("PersonID"); }); 

问题是您有多个级联删除路径,可能会尝试删除DB中BookingPeople表中的同一行。

您可以通过使用Fluent API在一对多关系中禁用级联删除来避免此类不明确的删除路径:

  modelBuilder.Entity() .HasRequired(s => s.Contact) .WithMany(s => s.aBookings) .HasForeignKey(s => s.ContactId) .WillCascadeOnDelete(false); 

或者通过将关系定义为可选(使用可为空的外键,但无法使用Fluent Api配置与级联删除的关系)。

  modelBuilder.Entity() .HasOptional(s => s.Contact) .WithMany(s => s.aBookings) .HasForeignKey(s => s.ContactId);// ContactId is a nullable FK property 

此外,您可以使用以下命令删除级联删除约定:

 modelBuilder.Conventions.Remove(); 

或者在多对多关系的情况下:

 modelBuilder.Conventions.Remove(); 

如果您在删除时需要删除所有与Person关联的Bookings ,我的建议是将一对多关系配置为可选,并覆盖SaveChanges方法:

 public override int SaveChanges() { Bookings.Local .Where(r => r.ContactId == null) .ToList() .ForEach(r => Bookings.Remove(r)); return base.SaveChanges(); } 

如果依赖实体上的外键可以为空,则Code First不会在关系上设置级联删除,并且当删除主体时,外键将设置为null 。 这样,您可以在SaveChanges方法中找到孤立并删除它们