web-dev-qa-db-ja.com

最初にEFコードのテーブルリレーションシップでカスケード削除が有効になっていることをどのように確認しますか?

Code-firstを使用してテーブルでCASCADE DELETEを有効にしたいと思います。モデルを最初から再作成すると、関係が自動的に設定されていても、CASCADE DELETEは設定されません。奇妙なことに、多対多の関係を持つ一部のテーブルでこれを有効にしても、問題が発生する可能性があります。

セットアップ:テーブルA <-テーブルB.

テーブルBのFKは、テーブルAのPKを指します。

なぜこれはうまくいかないのですか?

28
jaffa

カスケード削除が行われない理由として考えられるのは、関係がオプションであることです。例:

_public class Category
{
    public int CategoryId { get; set; }
}

public class Product
{
    public int ProductId { get; set; }
    public Category Category { get; set; }
}
_

このモデルでは、Categoryテーブルへの外部キーを持つProductテーブルを取得しますが、このキーはnull可能であり、デフォルトではデータベースにカスケード削除設定はありません。

必要な関係が必要な場合は、2つのオプションがあります。

注釈:

_public class Product
{
    public int ProductId { get; set; }
    [Required]
    public Category Category { get; set; }
}
_

Fluent API:

_modelBuilder.Entity<Product>()
            .HasRequired(p => p.Category)
            .WithMany();
_

どちらの場合も、カスケード削除は自動的に構成されます。

関係をオプションにしたいが、カスケード削除が必要な場合は、これを明示的に設定する必要があります。

_modelBuilder.Entity<Product>()
            .HasOptional(p => p.Category)
            .WithMany()
            .WillCascadeOnDelete(true);
_

編集:最後のコードスニペットでは、単に.WillCascadeOnDelete()と書くこともできます。このパラメーターなしのオーバーロードは、カスケード削除を設定するためにデフォルトでtrueになります。

詳細は documentation を参照してください

54
Slauma
modelBuilder
.Entity<Product>()
.HasRequired(p => p.Category)
.WithMany(x => x.Products)
.WillCascadeOnDelete(true);
0