SidewaysGravity
SidewaysGravity

Reputation: 612

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. 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.

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. 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.

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.

Upvotes: 9

Views: 3150

Answers (3)

Umair Ishaq
Umair Ishaq

Reputation: 752

I assume that the the same context, this.DB, is being used in this.getValidObject(id) to retrieve an entity. If that is the case, in the exception block call: this.DB.detach(deleteme). That should prevent the SaveChanges() to try to delete the problematic entity on the next iteration.

Upvotes: 9

Mr.GT
Mr.GT

Reputation: 310

If I understood correctly, you cannot remove the entity(Item) because it has a foreign key association(child) to it.
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.

Upvotes: 0

robrich
robrich

Reputation: 13205

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. You could also try creating a new DataContext for each loop such that the old, failed DataContext's state on the world is irrelevant.

Upvotes: 0

Related Questions