Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded. Refresh ObjectStateManager entries.

I don’t know how many times when I was debugging my application which had two databases communicating, I got the following error :

Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded. Refresh ObjectStateManager entries.

This basically means something updated the row since the last time you pulled information from it. This will throw a OptimisticConcurrencyException.

Solution 1 : Logic Error

The first thing I would try is actually stepping through your application. More times then not I had a rouge function updating a column on a child form, thus throwing this exception. If you are absolutely sure this is not the case, then proceed on to the other solutions.

Solution 2 : Catch the exception and output the error

Alex James wrote a nice article about how to use Optimistic Concurrency in the entity framework and how to trap and handle OptimisticConcurrencyException correctly. His method of handling resembles the following :

catch (OptimisticConcurrencyException ex)
{
    ObjectStateEntry entry = ex.StateEntries[0];
    Post post = entry.Entity as Post; //Post is the entity name he is using. Rename it with yours
    Console.WriteLine("Failed to save {0} because it was changed in the database", post.Title);
}

Solution 3 : Throw on your SQL detective hat with SQL Profiler

The SQL Profiler can be quite handy in determining what the Entity Framework is actually doing in the background. Here’s how to get started :

  • Start -> SQL Server 2008 R2 (Or your current version) -> Performance tools -> SQL Server Profiler
  • File -> New Trace. Enter in your SQL Server information here. Hit Connect
  • Enter a Trace name and output if you desire. Hit Run
  • Run the method that caused the exception
  • Click the red box near the top of the application, and search for your update in the events listed.

Solution 4 : Consider Who Should Win

If you know that the concurrency exception might happen in a non development environment, a different approach should be taken. Actually handle the error so that either the client will overwrite the changes, or the server will refuse update. I will preface this with though I would notify the user of the error, and have them decide what to do in each case. If you have a reoccurring exception, then you are probably doing something wrong.

Client Wins

try
{
    dbContext.SaveChanges();
}
catch (OptimisticConcurrencyException)
{
    dbContext.Refresh(RefreshMode.ClientWins, EntityObject); // Last in wins
}

Server Wins

try
{
    dbContext.SaveChanges();
}
catch (OptimisticConcurrencyException)
{
dbContext.Refresh(RefreshMode.StoreWins, EntityObject); // First one in wins
}

More Information :

http://www.codeproject.com/Articles/90762/Entity-Framework-4-EF4-Adventures

http://msdn.microsoft.com/en-us/library/bb738618.aspx

http://msdn.microsoft.com/en-us/library/bb399228.aspx

Jacob Saylor

Software developer in Kentucky

2 Responses

  1. try catch block is not working. exception occurs in try block and cursor doesnt step in to catch block.

    do you know why?

Leave a Reply to enescinarnes Cancel reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: