【问题标题】:Entity Framework; How to handle an exception in foreach loop and keep iterating实体框架;如何处理foreach循环中的异常并保持迭代
【发布时间】:2012-05-23 14:38:47
【问题描述】:

当我使用以下代码遍历 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,大多数人会先处理所有删除对象,然后保存更改,这样它就是一个事务。但我需要它单独处理每个事务,因此单个故障不会停止其余事务。

我正在使用实体框架 4。

对于这个特定示例,我得到的异常是由于外键与要删除的项目相关联。虽然在生产中我将处理这种情况,但无论异常是什么,它都应该能够继续。

【问题讨论】:

  • 什么是 ListData? List&lt;&gt;IQueryable&lt;&gt; ?
  • 我已更新代码以显示更多上下文。

标签: c# asp.net-mvc entity-framework


【解决方案1】:

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

【讨论】:

  • 是的,它使用相同的上下文。分离效果很好,并且易于实施。谢谢
  • 对于 EF4 和更新版本,请阅读 stackoverflow.com/q/4168073/37760 了解如何访问 Detach 方法。
【解决方案2】:

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

【讨论】:

  • 是否可以取消标记更改,以便异常后对 SaveChanges 的下一次调用不会尝试再次删除前一项并重新引发异常。我将尝试创建一个新的数据上下文,看看是否可行。
【解决方案3】:

如果我理解正确,您不能删除实体(项目),因为它有一个外键关联(子)。
您首先必须使用要删除的父(项目)更新所有子(相关)实体,通过删除关系,更新实体以与替代父(项目)相关或删除子实体(实体),然后最后移除 Parent(Item) 实体。

【讨论】:

  • 是的,我理解这一点,并且会在这种情况下这样做。但是如果有任何类型的异常,我希望能够继续迭代,并且我可能无法正确处理异常,在这种情况下,我只会通知用户它无法删除,因为到一个错误。
猜你喜欢
  • 2010-10-08
  • 1970-01-01
  • 2015-06-27
  • 2013-03-07
  • 1970-01-01
  • 2013-11-03
  • 2011-10-19
  • 1970-01-01
  • 2023-03-11
相关资源
最近更新 更多