9

次のコードを使用してforeachを反復処理すると、発生した最初の例外が正常にキャッチされ、IDがエラーリストに追加されます。ループの後続のすべての反復で、前の例外をキャッチし続けます。

例外を適切にキャッチし、失敗したDeleteObjectリクエストを元に戻すかクリアして、後続の削除を実行できるようにするにはどうすればよいですか。

public ActionResult Delete(int[] ListData)
{
    List<int> removed = new List<int>();
    List<int> error = new List<int>();
    Item deleteMe;
    foreach (var id in ListData)
    {
        deleteMe = this.getValidObject(id);
        if (deleteMe == null)
        {
            error.Add(id);
            continue;
        }

        try
        {
            this.DB.Items.DeleteObject(deleteMe);
            this.DB.SaveChanges();
            removed.Add(id);
        }
        catch (DataException ex)
        {
            // revert change to this.DB.Items?
            error.Add(id);
        }
    }
    if (error.Count > 0)
    {
        return Json(new { Success = false, Removed = removed, Error = error });
    }
    return Json(new { Success = true, Removed = removed });
}

私はSOとgoogleを検索しましたが、ほとんどの人は最初にすべての削除オブジェクトを処理してから、1つのトランザクションになるように変更を保存します。ただし、1回の失敗で残りのトランザクションが停止しないように、各トランザクションを個別に処理する必要があります。

EntityFramework4を使用しています。

この特定の例で得られる例外は、削除されるアイテムに関連付けられている外部キーが原因です。本番環境ではこのシナリオを処理しますが、例外が何であっても続行できるはずです。

4

3 に答える 3

9

エンティティを取得するために同じコンテキストthis.DBが使用されていると思います。this.getValidObject(id)その場合は、例外ブロックで次のように呼び出しますthis.DB.detach(deleteme)SaveChanges()これにより、が次の反復で問題のあるエンティティを削除しようとするのを防ぐことができます。

于 2012-05-23T15:39:21.363 に答える
0

あなたが提示するコードはよさそうだ。あなたが見るエラーは何ですか?お気づきのように、this.DB.Itemsのタグを解除する必要があるかもしれませんが、私はそうは思いません。また、ループごとに新しいDataContextを作成して、失敗した古いDataContextの世界の状態が無関係になるようにすることもできます。

于 2012-05-23T14:47:01.457 に答える
0

私が正しく理解していれば、エンティティ(アイテム)には外部キーの関連付け(子)があるため、削除することはできません。
最初に、削除する親(アイテム)を使用して、関係を削除するか、代替の親(アイテム)を関連付けるようにエンティティを更新するか、子エンティティ(エンティティ)を削除して、すべての子(関連)エンティティを更新する必要があります。最後に、Parent(Item)エンティティを削除します。

于 2012-05-23T15:12:36.590 に答える