Entity Framework: "Store update, insert, or delete statement affected an unexpected number of rows (0)."

I ran into this and it was caused by the entity's ID (key) field not being set. Thus when the context went to save the data, it could not find an ID = 0. Be sure to place a break point in your update statement and verify that the entity's ID has been set.

From Paul Bellora's comment

I had this exact issue, caused by forgetting to include the hidden ID input in the .cshtml edit page


That's a side-effect of a feature called optimistic concurrency.

Not 100% sure how to turn it on/off in Entity Framework but basically what it's telling you is that between when you grabbed the data out of the database and when you saved your changes someone else has changed the data (Which meant when you went to save it 0 rows actually got updated). In SQL terms, their update query's where clause contains the original value of every field in the row, and if 0 rows are affected it knows something's gone wrong.

The idea behind it is that you won't end up overwriting a change that your application didn't know has happened - it's basically a little safety measure thrown in by .NET on all your updates.

If it's consistent, odds are it's happening within your own logic (EG: You're actually updating the data yourself in another method in-between the select and the update), but it could be simply a race condition between two applications.


Wow, lots of answers, but I got this error when I did something slightly different that no on else has mentioned.

Long story short, if you create a new object and tell EF that its modified using the EntityState.Modified then it will throw this error as it doesn't yet exist in the database. Here is my code:

MyObject foo = new MyObject()
{
    someAttribute = someValue
};

context.Entry(foo).State = EntityState.Modified;
context.SaveChanges();

Yes, this seems daft, but it arose because the method in question used to have foo passed to it having been created earlier on, now it only has someValue passed to it and creates foo itself.

Easy fix, just change EntityState.Modified to EntityState.Added or change that whole line to:

context.MyObject.Add(foo);