2012/11/22

【EF CodeFirst】リレーションの連鎖削除について

 何かすごく久しぶりの更新なのに大した話ではないんですが、メモついでに…。

 コードファーストでリレーションを組んだ場合の連鎖削除についてです。
 まぁ、以下のようなCategoryとSubCategoryと名付けた親子のテーブルがあるとします。

Categoryテーブル
public class Category
{
    public int Id { get; set; }

    public string Name { get; set; }

    public virtual ICollection<subcategory> SubCategories { get; set; }
}

SubCategoryテーブル
public class SubCategory
{
    public int Id { get; set; }

    public int ClassId { get; set; }

    public string Name { get; set; }

    public virtual Category Category { get; set; }
}

 見ての通り、ClassIdを外部キーとしてリレーションするわけですが、Categoryのデータを削除した場合、SubCategoryのデータはどうなるのでしょうか?答えは連鎖削除されちゃいます。まったくEntityFrameworkって気が利いてますねって感じです。

 では逆に連鎖削除してほしくない時はどうすればよいのでしょうか?自分、他のテーブルとの関係で連鎖削除OFFにしたくてずいぶん悩みました。答えは以下のようにテーブルを変更します。

Categoryテーブル
public class Category
{
    public int Id { get; set; }

    public string Name { get; set; }

    public virtual ICollection<subcategory> SubCategories { get; set; }
}

SubCategoryテーブル
public class SubCategory
{
    public int Id { get; set; }

    public int? ClassId { get; set; }

    public string Name { get; set; }

    public virtual Category Category { get; set; }
}

 ちょっとどこが変わったか分かりにくいですが、SubCategoryのClassIdの型をNull許容型に変更しています。こうすることでリレーションを保ったまま連鎖削除を切ることができます。

 ちなみにこれらの設定はMigrationのForeignKeyをいじることでも行うことができます。
pagetop