9

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.

tereško
  • 58,060
  • 25
  • 98
  • 150
SidewaysGravity
  • 562
  • 5
  • 14

3 Answers3

9

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.

GoRoS
  • 5,183
  • 2
  • 43
  • 66
Umair Ishaq
  • 752
  • 9
  • 22
0

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.

robrich
  • 13,017
  • 7
  • 36
  • 63
  • Is it possible to un-tag the change so that the next call to SaveChanges after the exception will not attempt to delete the previous item again and rethrow the exception. I will try creating a new data context and see if that works. – SidewaysGravity May 23 '12 at 15:18
0

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.

Mr.GT
  • 310
  • 4
  • 12
  • Yes, I understand that and will be doing just that for that scenario. But if there are exceptions of any kind, I want to be able to continue iterating, and it may be possible that I will not be able to properly handle the exception in which case I will just notify the user that it could not be deleted due to an error. – SidewaysGravity May 23 '12 at 15:16