How to ignore a DbUpdateConcurrencyException when deleting an entity

entity-framework

Question

I have an app that reads a lot of data into memory and processes it in a batches.

What I want is for entity framework to ignore DbUpdateConcurrencyException when deleting an entity that has already been deleted.

The reason is that by the time an entity has been processed and marked for deletion, it may already have been deleted from the DB.

Obliviously deleting a row that has already been deleted isn't a problem and shouldn't cause an error, I just need a way to tell entity framework that :)

Example

Db.Entry(itemToRemove).State = EntityState.Deleted;
Db.SaveChanges();

Causes an error if itemToRemove has already been deleted.

Note: Db.Configuration.ValidateOnSaveEnabled = false; doesn't fix this as another thread suggested.

1
15
10/10/2013 12:02:02 PM

Accepted Answer

How about?

Db.Entry(itemToRemove).State = EntityState.Deleted;

bool saveFailed;
do
{
    saveFailed = false;
    try
    {
       Db.SaveChanges();
    }
    catch(DbUpdateConcurrencyException ex)
    {
       saveFailed = true;
       var entry = ex.Entries.Single();
       //The MSDN examples use Single so I think there will be only one
       //but if you prefer - do it for all entries
       //foreach(var entry in ex.Entries)
       //{
       if(entry.State == EntityState.Deleted)
          //When EF deletes an item its state is set to Detached
          //http://msdn.microsoft.com/en-us/data/jj592676.aspx
          entry.State = EntityState.Detached;
       else
          entry.OriginalValues.SetValues(entry.GetDatabaseValues());
          //throw; //You may prefer not to resolve when updating
       //}
    }
} while (saveFailed);

More here: Resolving optimistic concurrency exceptions

17
10/11/2013 3:46:18 PM

Popular Answer

You could handle the DbUpdateConcurrencyException and then call Refresh(RefreshMode,IEnumerable) with RefreshMode.StoreWins and your deleted entities as parameter.

try{
  Db.Entry(itemToRemove).State = EntityState.Deleted;
  Db.SaveChanges();
}
catch(DbUpdateConcurrencyException)
{
  IObjectContextAdapter adapter = Db;

  adapter.ObjectContext.Refresh(RefreshMode.StoreWins, context.ObjectStateManager.GetObjectStateEntries(System.Data.EntityState.Deleted));
  Db.SaveChanges();
}


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow