Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can i ignore a DbUpdateConcurrencyException with my Entity Framework code?

Is there any way I can tell EF to not worry about the number of rows a DELETE or UPDATE do or don't do?

I'm trying to delete a row from the database, but because the row doesn't exist, EF throws an exception: DbUpdateConcurrencyException .. saying 0 rows were affected. This is right -> no rows were deleted. But that's totally fine .. cause there's no data.

I don't really want to do a round-trip to the DB to see if that row exists .. and if so .. then try and delete it.

If i try and swallow the exception in a try / catch block, then the rest of the items to be deleted do NOT get sent to the db, when I try to SaveChanges() ... which is bad.

eg.

Delete(new Foo(1));
Delete(new Foo(2));
Delete(new Foo(3));
SaveChanges(); // <-- Throws the exception.

// DB Trace : DELETE FROM Foo WHERE Id = 1;

and thats it.. there's no trace showing record 2 or 3 trying to get deleted .. because the exception stops everything :(

Any ideas?

UPDATE

How does Delete work? Here's the code... (simplified and strongly typed)

public void Delete(Foo foo)
{
    if (foo == null)
    {
        throw new ArgumentNullException("foo");
    }

    Foo attachedEntity = Context.Set<Foo>().Local.FirstOrDefault(x => x.Id > 0);

    if (attachedEntity != null)
    {
        // Entity already in object graph - remove entity.
        Context.Set<Foo>().Remove(attachedEntity);
    }
    else
    {
        // Entity not in object graph, attach and set EntityState to Deleted.
        Context.Entry(foo).State = EntityState.Deleted;
    }
}
like image 344
Pure.Krome Avatar asked Feb 17 '11 01:02

Pure.Krome


People also ask

How do I resolve DbUpdateConcurrencyException?

Custom resolution of optimistic concurrency exceptions SaveChanges(); } catch (DbUpdateConcurrencyException ex) { saveFailed = true; // Get the current entity values and the values in the database var entry = ex. Entries. Single(); var currentValues = entry. CurrentValues; var databaseValues = entry.

How do I fix concurrency issues in C#?

Concurrency problems can be solved by implementing a proper "Locking strategy". Locks prevent action on a resource to be performed when some other resource is already performing some action on it.

How do you configure entity framework for optimistic concurrency?

If you do want to implement this approach to concurrency, you have to mark all non-primary-key properties in the entity you want to track concurrency for by adding the ConcurrencyCheck attribute to them. That change enables the Entity Framework to include all columns in the SQL WHERE clause of UPDATE statements.


1 Answers

I think the behavior of EF is correct - simply you must execute commands only for objects which are present in DB. It is not for scenarios like: "I will try it and we will see...". If you can't be sure that object exists in DB and you don't want to do round trip (which I think is the best idea because deleting detached object can have several other pitfalls especially if object participates in independent associations) you should use DbContext.Database.SqlCommand and run store procedure.

The correct way to handle DbUpdateConcurrencyException is described here => After each exception you should resolve confilicts (in your case it means remove problematic entity from DbContext) and execute SaveChanges again.

like image 132
Ladislav Mrnka Avatar answered Oct 20 '22 00:10

Ladislav Mrnka