实体框架核心级联删除一对多关系

时间:2017-01-18 05:09:49

标签: c# entity-framework entity-framework-core

public class Station : IEntitie
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }

    public virtual ICollection<RegulatorySchedule> RegulatoryScheduleDispatchStations { get; set; }    

    public virtual ICollection<RegulatorySchedule> RegulatoryScheduleDestinationStations { get; set; }   
}

public class RegulatorySchedule : IEntitie
{
    [Key]
    public int Id { get; set; }

    public virtual Station DispatchStation { get; set; }      

    public virtual Station DestinationStation { get; set; }     
}


protected override void OnModelCreating(ModelBuilder modelBuilder)
{
        modelBuilder.Entity<RegulatorySchedule>()
            .HasOne(s => s.DestinationStation)
            .WithMany(s => s.RegulatoryScheduleDestinationStations)
            .OnDelete(Microsoft.EntityFrameworkCore.Metadata.DeleteBehavior.Restrict);

        modelBuilder.Entity<RegulatorySchedule>()
            .HasOne(s => s.DispatchStation)
            .WithMany(s => s.RegulatoryScheduleDispatchStations)
            .OnDelete(Microsoft.EntityFrameworkCore.Metadata.DeleteBehavior.Restrict);
}

仅当我在删除Restrict OnDelete (Microsoft.EntityFrameworkCore.Metadata.DeleteBehavior.Restrict)时清楚地暴露行为时,才会在迁移期间创建数据库。 否则,它会引发异常:

  

&#34;介绍FOREIGN KEY约束   &#39; FK_RegulatorySchedules_Stations_DispatchStationId&#39;桌子上   &#39; RegulatorySchedules&#39;可能会导致循环或多个级联路径。     指定ON DELETE NO ACTION或ON UPDATE NO ACTION,或修改其他   FOREIGN KEY约束。&#34;

我需要删除表格的Station Station以及与表格相关的属性RegulatorySchedules DispatchStation和DestinationStation暴露于NULL。 但限制选项当你删除我无法放置的SetNull时会有异常。 告诉我该怎么做?

2 个答案:

答案 0 :(得分:13)

描述&#34;问题&#34;与实体框架无关 - 这是对MS SQL Server本身的限制。具有多个FK的表可能只有一个具有级联删除。

所以,一旦你需要两个FK都有级联 - 你应该实现这样的&#34;清理&#34;在你的代码中。将一个(或两个)FK设置为​​DeleteBehavior.Restrict,并在删除Station之前在您的控制器/服务中手动查找并删除所有相关的RegulatorySchedule

答案 1 :(得分:4)

德米特里(Dmitry)的回答非常有效。对于任何未来的旅行者,下面都提供了映射表的工作示例。

该代码位于您的OnModelCreating(ModelBuilder modelBuilder)方法中 DbContext类:

modelBuilder.Entity<AB>()
            .HasKey(e => new { e.AId, e.BId});

modelBuilder.Entity<AB>()
            .HasOne(e => e.A)
            .WithMany(e => e.ABs)
            .HasForeignKey(e => e.AId)
            .OnDelete(DeleteBehavior.Cascade); // <= This entity has cascading behaviour on deletion

modelBuilder.Entity<AB>()
            .HasOne(e => e.B)
            .WithMany(e => e.ABs)
            .HasForeignKey(e => e.BId)
            .OnDelete(DeleteBehavior.Restrict); // <= This entity has restricted behaviour on deletion