当我使用以下代码迭代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和谷歌,大多数人会首先处理所有删除对象,然后保存更改,以便它是一个事务。但我需要它来单独处理每个事务,因此单个故障不会停止其余的事务。
我正在使用Entity Framework 4。
由于外键与要删除的项目相关联而导致此特定示例的异常。在生产中,我将处理这种情况,无论异常是什么,它都应该能够继续。
答案 0 :(得分:7)
我假设在this.DB
中使用相同的上下文this.getValidObject(id)
来检索实体。如果是这种情况,则在异常块调用中:this.DB.detach(deleteme)
。这应该阻止SaveChanges()
尝试在下一次迭代中删除有问题的实体。
答案 1 :(得分:0)
您提供的代码看起来不错。你看到的错误是什么?正如你所指出的,也许你需要在this.DB.Items中取消标记,尽管我不这么认为。您还可以尝试为每个循环创建一个新的DataContext,这样世界上失败的旧DataContext状态就无关紧要了。
答案 2 :(得分:0)
如果我理解正确,你不能删除实体(Item),因为它有一个外键关联(子)。
您首先必须使用要删除的父(项)更新所有子(相关)实体,方法是删除关系,更新实体以关联替代父项(项)或删除子实体(实体)然后最后删除父(项)实体。