简体   繁体   English

实体框架; 如何处理foreach循环中的异常并继续迭代

[英]Entity Framework; How to handle an exception in foreach loop and keep iterating

When I iterate through a foreach with the following code it successfully catches the first exception that occurs and adds the id to my error list. 当我使用以下代码遍历foreach时,它成功捕获发生的第一个异常并将id添加到我的错误列表中。 On all the subsequent iterations of the loop, it will continue to catch the previous exception. 在循环的所有后续迭代中,它将继续捕获先前的异常。

How can I appropriately catch the exception and undo or clear the failed DeleteObject request so that subsequent deletes can be performed. 如何正确捕获异常并撤消或清除失败的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 });
}

I have searched SO and google and most people will process all the delete objects first and then save changes so that it is one transaction. 我搜索了SO和谷歌,大多数人会首先处理所有删除对象,然后保存更改,以便它是一个事务。 But I need it to process each transaction individually so a single failure does not stop the rest of the transactions. 但我需要它来单独处理每个事务,因此单个故障不会停止其余的事务。

I am using Entity Framework 4. 我正在使用Entity Framework 4。

The exception I get for this specific example caused by foreign keys being associated to the item that is being removed. 我为此特定示例获得的异常是由外键与要删除的项关联引起的。 While in production I will be handling this scenario, it should be able to continue on no matter what the exception is. 在生产中我将处理这种情况,它应该能够继续,无论例外是什么。

I assume that the the same context, this.DB , is being used in this.getValidObject(id) to retrieve an entity. 我假设在this.DB this.getValidObject(id)使用相同的上下文this.DB来检索实体。 If that is the case, in the exception block call: this.DB.detach(deleteme) . 如果是这种情况,则在异常块调用中: this.DB.detach(deleteme) That should prevent the SaveChanges() to try to delete the problematic entity on the next iteration. 这应该阻止SaveChanges()尝试在下一次迭代中删除有问题的实体。

The code you present looks good. 你提供的代码看起来不错。 What is the error you see? 你看到的错误是什么? As you've noted, maybe you need to un-tag something in this.DB.Items, though I don't think so. 正如你所指出的,也许你需要在this.DB.Items中取消标记,尽管我不这么认为。 You could also try creating a new DataContext for each loop such that the old, failed DataContext's state on the world is irrelevant. 您还可以尝试为每个循环创建一个新的DataContext,以使旧的,失败的DataContext在世界上的状态无关紧要。

If I understood correctly, you cannot remove the entity(Item) because it has a foreign key association(child) to it. 如果我理解正确,则无法删除实体(Item),因为它具有外键关联(子)。
You will first have to update all child(related) entities using the Parent(Item) you want to delete, by removing the relationship, updating the entity to relate too an alternative parent(Item) or deleting the child entity(entities) and then finally removing the Parent(Item) entity. 您首先必须使用要删除的父(项)更新所有子(相关)实体,方法是删除关系,更新实体以关联替代父项(项)或删除子实体(实体)然后最后删除Parent(Item)实体。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM