C# 实体框架;如何处理foreach循环中的异常并保持迭代

C# 实体框架;如何处理foreach循环中的异常并保持迭代,c#,asp.net-mvc,entity-framework,C#,Asp.net Mvc,Entity Framework,当我用下面的代码迭代foreach时,它成功地捕获了发生的第一个异常,并将id添加到错误列表中。在循环的所有后续迭代中,它将继续捕获以前的异常 如何正确捕获异常并撤消或清除失败的DeleteObject请求,以便执行后续删除 public ActionResult Delete(int[] ListData) { List<int> removed = new List<int>(); List<int> error = new List<

当我用下面的代码迭代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 });
}
公共操作结果删除(int[]ListData) { 列表已删除=新列表(); 列表错误=新建列表(); 项目删除我; foreach(ListData中的变量id) { deleteMe=this.getValidObject(id); 如果(deleteMe==null) { 错误。添加(id); 继续; } 尝试 { this.DB.Items.DeleteObject(deleteMe); this.DB.SaveChanges(); 删除。添加(id); } 捕获(DataException ex) { //是否将更改还原为this.DB.Items? 错误。添加(id); } } 如果(error.Count>0) { 返回Json(新的{Success=false,Removed=Removed,Error=Error}); } 返回Json(新的{Success=true,Removed=Removed}); } 我搜索过SO和google,大多数人会先处理所有的删除对象,然后保存更改,这样它就是一个事务。但是我需要它单独处理每个事务,这样一个单一的故障不会停止其余的事务

我使用的是实体框架4


对于这个特定示例,我得到的异常是由与要删除的项关联的外键引起的。在生产中,我将处理这个场景,无论出现什么异常,它都应该能够继续运行。

您提供的代码看起来不错。您看到的错误是什么?正如您所指出的,也许您需要在this.DB.Items中取消标记某些内容,尽管我不这么认为。您还可以尝试为每个循环创建一个新的DataContext,以便旧的、失败的DataContext在世界上的状态是不相关的。

如果我理解正确,您无法删除该实体(项),因为它有一个外键关联(子项)。

首先,您必须使用要删除的父(项)更新所有子(相关)实体,方法是删除关系、更新实体以与备选父(项)关联或删除子实体(项),然后最后删除父(项)实体。

我假设相同的上下文,
this.DB
,正在
this.getValidObject(id)
中使用以检索实体。如果是这种情况,在异常块调用中:
this.DB.detach(deleteme)
。这将防止
SaveChanges()
在下一次迭代中尝试删除有问题的实体

什么是列表数据?
列表
IQueryable
?我已经更新了代码以显示更多的上下文。是的,我理解这一点,并且将针对该场景这样做。但是如果有任何类型的异常,我希望能够继续迭代,我可能无法正确处理异常,在这种情况下,我只会通知用户由于错误而无法删除该异常。是否可以取消标记更改,以便在异常发生后对SaveChanges的下一次调用不会再次尝试删除上一项并重新显示异常。我将尝试创建一个新的数据上下文,看看是否有效。是的,它使用的是相同的上下文。Detach工作得很好,实现起来很简单。感谢EF4和更高版本,阅读本文了解如何访问Detach方法。