Entity Framework Code first: cycles or multiple cascade paths

混江龙づ霸主 提交于 2019-11-27 09:09:45

The problem is you have multiple paths of cascade deletes that could end trying to delete the same row in the BookingPeople table in DB.

You can avoid such ambiguous delete paths by either disabling cascading delete in the one-to-many relationship using Fluent API:

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

Or by defining the relationship as optional (with a nullable foreign key, but you can not configure the relationship with cascade delete using Fluent Api).

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

Also, you can remove the cascade delete convention by using:

modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();

Or in the case of the many-to-many relationship:

modelBuilder.Conventions.Remove<ManyToManyCascadeDeleteConvention>();

If you need to delete all the Bookings asociated with a Person when you delete it, my advice is configure the one-to-many relationship as optional, and override the SaveChanges method:

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

    return base.SaveChanges();
 }

If a foreign key on the dependent entity is nullable, Code First does not set cascade delete on the relationship, and when the principal is deleted the foreign key will be set to null. This way, you can find the orphans in the SaveChanges method and delete them

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!