2012-05-23 14 views
9

foreachを次のコードで反復処理すると、発生した最初の例外が正常にキャッチされ、エラーリストにIDが追加されます。ループのその後のすべての反復で、前の例外を引き続き捕捉します。エンティティフレームワーク。 foreachループで例外を処理して反復処理を続ける方法

例外を適切にキャッチし、失敗した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つのトランザクションであるように、変更を保存しますしています。しかし、個々のトランザクションを個別に処理する必要があるため、単一の障害によって残りのトランザクションが停止することはありません。

私は、Entity Frameworkの4

私が削除されているアイテムに関連付けられている外部キーによって引き起こされるこの特定の例のために得る例外を使用しています。私はこのシナリオを処理する予定ですが、例外が何であっても継続することができます。

+0

ListDataとは何ですか? 'List <>'か 'IQueryable <>'か? –

+0

私はより多くの文脈を示すためにコードを更新しました。 – SidewaysGravity

答えて

7

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

+0

はい、同じコンテキストを使用しています。デタッチはうまくいっており、実装が簡単です。ありがとう – SidewaysGravity

+0

EF4以降では、Detachメソッドへのアクセス方法については、このhttp://stackoverflow.com/q/4168073/37760を参照してください。 – Corin

0

あなたのコードはよさそうです。表示されるエラーは何ですか?あなたが指摘したように、おそらくあなたはthis.DB.Itemsのタグを解除する必要がありますが、私はそうは思わない。また、古い、失敗したDataContextの状態が無関係であるように、各ループの新しいDataContextを作成してみることもできます。

+0

変更後にSaveChangesを呼び出すと、前の項目を再度削除して例外を再発行しようとしないように、変更のタグを解除することはできますか?新しいデータ・コンテキストを作成し、そのデータ・コンテキストが動作するかどうかを確認します。 – SidewaysGravity

0

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

+0

はい、私はそれを理解しており、そのシナリオのためだけにやっています。しかし、何らかの例外がある場合、私は反復を続行できるようにしたい、そして、私は例外を適切に処理できない可能性があります。その場合、削除されなかったことをユーザーに通知するだけですエラーになります。 – SidewaysGravity