web-dev-qa-db-ja.com

Entity Framework Coreカスケードは、1対多の関係を削除します

_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)を削除するときの動作を明確に公開した場合にのみ、データベースが移行中に作成されます。それ以外の場合、例外がスローされます。

「テーブル 'RegulatorySchedules'にFOREIGN KEY制約 'FK_RegulatorySchedules_Stations_DispatchStationId'を導入すると、サイクルまたは複数のカスケードパスが発生する可能性があります。ONDELETE NO ACTIONまたはON UPDATE NO ACTIONを指定するか、他のFOREIGN KEY制約を変更します。」

テーブルのステーションステーションおよびテーブル関連のプロパティRegulatorySchedules DispatchStationおよびDestinationStationをNULLに公開する必要があります。ただし、制限オプションには、配置できないSetNullを削除する場合の例外があります。どうなるか教えて?

11
Aldmi

説明されている「問題」はEntity Frameworkとは関係ありません-これはMS SQL Server自体の制限です。複数のFKを含むテーブルには、cascadedeleteのあるFKが1つだけある場合があります。

したがって、両方のFKにcascadeが必要になったらすぐに、そのような「クリーンアップ」をコードに実装する必要があります。 1つ(または両方)のFKをDeleteBehavior.Restrictに設定し、Stationを削除する前にコントローラー/サービスで、関連するすべてのRegulatoryScheduleを手動で見つけて削除します

17
Dmitry

ドミトリーの答えは完璧に機能しました。将来の旅行者のために、以下のマッピングテーブルの実際のサンプル。

コードは、DbContextクラスのOnModelCreating(ModelBuilder modelBuilder)メソッドにあります。

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
4
mmr