Search code examples
c#entity-framework-4objectcontext

Detaching an entity and saving the context on another attempt


I am trying to handle a situation in a bulk insert process where there may be entities with the same primary key, which of course is going to make SaveChanges throw an exception.

Here's what I have:

try
{
    _context.SaveChanges();
    _context.Dispose();
    _context = null;
    _context = SelectContext<T>();
    _commitCount = 0;
}
catch (System.Data.UpdateException updateEx)
{
    //Remove from _context all the entries that errored in the SaveChange() process...
    if (updateEx.StateEntries != null)
    {
        foreach (ObjectStateEntry stateEntry in updateEx.StateEntries)
        {

            if ((System.Data.EntityState)stateEntry.Entity.GetType().GetProperty("EntityState").GetValue(stateEntry.Entity, null) != System.Data.EntityState.Detached)
            {
                _context.Detach(stateEntry.Entity);
            }
         }

}

//Save context changes again this time without erroneous entries...
try
{
     _context.SaveChanges();
     _context.Dispose();
     _context = null;
     _context = SelectContext<T>();
     _commitCount = 0;
 }
 catch (Exception ex)
 {                  
   //Welp, at the point, I'm clueless...
 }

If I look in the ObjectStateManager, the entity is indeed removed (the count goes down by the number of time the foreach loop is iterated.)

But it still throws an exception on the second attempt, whinning about a dupe PK.

I tought detaching an entity was the same is if it was never in the context in the first place. Do I need to do something else ?

Thanks.


Solution

  • This is what I ended up doing in my case:

    _context.ObjectStateManager.ChangeObjectState(stateEntry.Entity, System.Data.EntityState.Unchanged);
    _context.ApplyOriginalValues<T>(entityType, (T)stateEntry.Entity);
    _context.Detach(stateEntry.Entity);
    

    After that, I'm able to save the context changes.