web-dev-qa-db-ja.com

カスケード削除のエンティティフレームワーク

Entity Framework 4.1で関連する行を削除することに問題があります。リレーション付きのテーブルがあります

Book 1 <---> * BookFormats

削除時にカスケードを設定しました:

ALTER TABLE [dbo].[BookFormats]  WITH CHECK ADD  CONSTRAINT [FK_BookFormats_Book] 
FOREIGN KEY([BookID]) REFERENCES [dbo].[Book] ([BookID]) on delete cascade

EDMXプロパティ

enter image description here

次に、BokFormatsオブジェクトに関連するすべてのBookアイテムを削除します。

 var originalBook = m.db.Book.First(x => x.BookID == bookId);
 originalBook.BookFormats.Clear();
 m.db.SaveChanges();

しかし、私はエラーが発生します:

操作が失敗しました:1つ以上の外部キープロパティがnull可能ではないため、関係を変更できませんでした。リレーションシップが変更されると、関連する外部キープロパティはnull値に設定されます。外部キーがnull値をサポートしない場合は、新しい関係を定義するか、foreign-keyプロパティに別のnull以外の値を割り当てるか、無関係なオブジェクトを削除する必要があります。

これらのオブジェクトを削除する方法についてのアイデアがなくなりました。何か案は?

13
Tony

カスケード削除の概念は次のとおりです。

DBからBookを削除すると、関連するすべてのBookFormatsがSQL Serverによって削除されます(Bookの削除がどのように開始されるかは問題ではないことに注意してくださいEFまたはraw SQL)。したがって、それはあなたのタスクとは何の関係もありません:「自分のBookFormatsに関連するすべてのBookを削除したい」。それを達成するには、次のようなものが必要です。

foreach(var m in m.db.BookFormats.Where(f=>f.BookID == bookID))
{
    m.db.BookFormats.Remove(m);
}
m.db.SaveChanges();
11
Vitaliy Kalinin

RemoveRangeを使用できます。

m.db.BookFormats.RemoveRange(originalBook.BookFormats);
m.db.SaveChanges();

しかし、これはEF 6.0用です

17
Saykor

データベースからBookFormatsを削除するのではなく、関係を削除して、BookFormatsをorpahningし、BookID列を[〜#〜 ] null [〜#〜]。データベースに配置した削除カスケードは、_When I delete the_ Book _, then delete all of the_ BookFormats _that have a_ BookID _equal to mine._と表示しています。Bookからフォーマットを削除している本を削除していません。

originalBook.BookFormats.Clear()の代わりに、次のようなものが必要です...

_List<int> idsToDelete = new List<int>();

foreach (BookFormat bf in originalBook.BookFormats)
{
    idsToDelete.Add(bf.ID);
}

foreach (int id in idsToDelete)
{
    BookFormat format = m.db.BookFormat.FirstOrDefault(x => x.ID == id);
    if (format != null)
    {
         m.db.DeleteBookFormat(format);
    }
}

m.db.SaveChanges();
_

それはそれらの線に沿ったものでなければなりません。 EFがEDMXで削除メソッドを構築する方法を覚えているのは、目の前にはありません。

4
bdparrish

私はそれをEF 6.1.3でテストしましたが、これは正常に動作するはずです。

 var originalBook = m.db.Book.First(x => x.BookID == bookId);
 originalBook.BookFormats.Clear();
 db.Books.Remove(originalBook);
 m.db.SaveChanges();
1
gbdavid

私はEF6を使用していますが、これは機能します。

        var itemBinding = db.ItemBinding.Where(x => x.BindingToId == id) ;
        foreach (var ib in itemBinding)
        {
            db.Item.Remove(ib.Item);
            db.ItemBinding.Remove(ib);
        }
        db.SaveChanges();
0
prespic