私は以下のオブジェクトをEFで定義しています。Entity Frameworkの子レコードの特定と削除
public class ItemA()
{
public virtual ICollection<ItemB> Items{ get; set; }
}
public class ItemB()
{
public virtual ICollection<ItemC> Items{ get; set; }
}
私のコードでは、次のことを行っています。 ItemAのインスタンスが移入され
myItemA.Items.Remove(myItemA.Items.FirstOrDefault(x => (int)x.Type == model.Type));
myItemA.Items.Add(new ItemB());
は、それが単一ItemBが含まれていると私は単純にItemBの新しいインスタンスでこれを置き換えたいです。メッセージを更新するために私のサービスに入ると、次のコードを呼び出すだけで新しいItemBが作成され、既存のItemBは親IDがnullの孤立した状態になります。 ItemBとItemC間のリンクはそのままです。
_dbContext.Entry(entity).State = EntityState.Modified;
_dbContext.SaveChanges();
だから、私は私がモデルで削除するItemB子と制約のセットアップがうまくいけば、カスケード子ItemCレコード、その後、孤立ItemBを削除することEFを伝える必要があることを知っています。しかし、私はそうする方法を見つけるのに苦労しています。
親アイテムをコンテクストから再取得してリストを比較し、それらを削除済みとしてマークしようとしましたが、プロキシを戻しているので、両方のオブジェクトは基本的に同じで、更新されたItemBのみを持ちます。元の。
var existingItem = GetItem(entity.Id);
または
var existing Items = GetItem(entity.Id).Items.ToList();
だから私は必要なもの、オリジナルItemA.Itemsは、彼らが削除されるEFを伝えることができるようにすることです。 EFに何かを削除するよう指示する方法はわかっていますが、削除する必要があるエンティティへの参照を取得することにのみ関心があります。このコードを追加する
EDIT
はそれが仕事になり、(子ItemC付き)孤立ItemBが削除されるようになりました、しかし、私の知る限りそれを理解するように、これは今、2つのトランザクション内で実行されます。
//Update Message
_dbContext.Entry(entity).State = EntityState.Modified;
_dbContext.SaveChanges();
//Remove any orphaned records
var itemsToRemove = _dbContext.Set<ItemB>().Where(x => x.ItemA == null).ToList();
_dbContext.Set<ItemB>().RemoveRange(itemsToRemove);
_dbContext.SaveChanges();
理想的には、この単一SaveChanges()
エンティティの状態を削除しようとしましたか? 'foreach(item.Itemsのvar子アイテム)dbContext.Entry(childItem).State = EntityState.Deleted;'? –
これは問題です。item.Itemsには削除したい項目が含まれていません。新しい項目Bのみが追加され、元のItemBは孤立したままになります。 – ChrisBint
削除して再追加する前のことを意味します。しかし、あなたは次の行で削除しようとしていますか? 'item.Items.Remove(item.Items.FirstOrDefault(x =>(int)x.Type == model.Type));'どこでアイテムを取得しますか?データベースから? –