views:

125

answers:

1

Hi,

In the Entity Framework, there are a few conditions which are handled at the database level, and passed back up to the EF as exceptions on a Context.SaveChanges().

If you are carrying out creation of new entities in a loop, you can handle the exception via the standard 'Try Catch' block, but how do you clear the problematic entity from the SaveChanges() queue?

For example (Moving the SaveChanges outside of the loop has no positive effect, so its shown here within the loop):

while(i < 1000)
{
    MyEntity Wibble = new MyEntity();
    Wibble.Name = "Test " + i.ToString();

    Context.AddToTests(Wibble);
    Context.SaveChanges();

}

If, for some reason, there already exists a Wibble which causes the insert to fail on a unique constraint in the database, I can handle the immediate exception in the loop.

However, it again fails on the next iteration, because the problematic Wibble instance still exists in the SaveChanges queue - how are you supposed to handle this?

You can certainly check beforehand if we are creating a duplicate Wibble, but this results in two round trips to the database. I don't mind handling the exception, I simply want to be made aware of the issue, ignore that record and move on.

Thoughts? Am I doing this wrong?

EDIT:

I have solved the immediate issue, but only for when you do the Context.SaveChanges() within the loop. If you just call SaveChanges() once, outside the end of the loop, my solution does not work - can anyone suggest an alternative method that would work?

A: 

As usual, I have solved it within 15 minutes of asking someone :)

The solution is to delete the entity object from the ObjectStateManager while handling the exception, which allows the loop to continue:

while(i < 1000)
{
    MyEntity Wibble = new MyEntity();
    Wibble.Name = "Test " + i.ToString();

    Context.AddToTests(Wibble);

    try
    {
        Context.SaveChanges();
    }
    catch
    {
        Context.ObjectStateManager.GetObjectStateEntry(Wibble).Delete();
    }

}
Moo