Jam*_*ers 4 c# sql-server entity-framework ef-fluent-api
我有一个Booking类,它有一个预订联系人(a Person)和一组导航属性(People),它们通过连接表链接到另一组导航属性(Bookings)Person.如何Booking为预订联系人关系启用级联删除生成表格?当我将它从流畅的API代码中删除时(启用了级联删除的默认设置),我从迁移中收到以下错误消息:
在'BookingPeople'表上引入FOREIGN KEY约束'FK_dbo.BookingPeople_dbo.People_PersonID'可能会导致循环或多个级联路径.指定ON DELETE NO ACTION或ON UPDATE NO ACTION,或修改其他FOREIGN KEY约束.
无法创建约束或索引.查看以前的错误.
modelBuilder.Entity<Person>()
.HasMany<Booking>(s => s.aBookings)
.WithRequired(s => s.Contact)
.HasForeignKey(s => s.ContactId);
modelBuilder.Entity<Booking>()
.HasMany(t => t.People)
.WithMany(t => t.Bookings)
.Map(m => {
m.ToTable("BookingPeople");
m.MapLeftKey("BookingID");
m.MapRightKey("PersonID");
});
Run Code Online (Sandbox Code Playgroud)
oct*_*ccl 20
问题是您有多个级联删除路径,可能会尝试删除BookingPeopleDB中表中的同一行.
您可以通过使用Fluent API在一对多关系中禁用级联删除来避免此类不明确的删除路径:
modelBuilder.Entity<Booking>()
.HasRequired(s => s.Contact)
.WithMany(s => s.aBookings)
.HasForeignKey(s => s.ContactId)
.WillCascadeOnDelete(false);
Run Code Online (Sandbox Code Playgroud)
或者通过将关系定义为可选(使用可为空的外键,但无法使用Fluent Api配置与级联删除的关系).
modelBuilder.Entity<Booking>()
.HasOptional(s => s.Contact)
.WithMany(s => s.aBookings)
.HasForeignKey(s => s.ContactId);// ContactId is a nullable FK property
Run Code Online (Sandbox Code Playgroud)
此外,您可以使用以下命令删除级联删除约定:
modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
Run Code Online (Sandbox Code Playgroud)
或者在多对多关系的情况下:
modelBuilder.Conventions.Remove<ManyToManyCascadeDeleteConvention>();
Run Code Online (Sandbox Code Playgroud)
如果你需要在删除时删除所有Bookings与a关联的Person,我的建议是将一对多关系配置为可选,并覆盖该SaveChanges方法:
public override int SaveChanges()
{
Bookings.Local
.Where(r => r.ContactId == null)
.ToList()
.ForEach(r => Bookings.Remove(r));
return base.SaveChanges();
}
Run Code Online (Sandbox Code Playgroud)
如果依赖实体上的外键可以为空,则Code First不会在关系上设置级联删除,并且当删除主体时,外键将设置为null.这样,您可以在SaveChanges方法中找到孤立并删除它们