Recently we updated an application to use Entity Framework Core 3.1. After the update, we noticed some of our tests failed with the error Attempted to update or delete an entity that does not exist in the store.
. When looking a little further, we noticed the exception type was Microsoft.EntityFrameworkCore.DbUpdateConcurrencyException
. So this error means we are trying to update something in the database that is not there.
Model
First, let’s take a look at the model we have. The parent item looks something like this:
public class Parent
{
public Guid? ID { get; set; }
public List<Child> ChildItems { get; private set; } = new List<Child>();
}
The Child
class looks like this:
public class Child
{
public Guid? ID { get; set; }
}
Adding the parent
In the code, the Parent
is created with the initial list of Child
items. Because the Parent
initially does not exist, we can add it by calling the DbContext.Parents.Add(Parent)
method. Where DbContext.Parents
is a DbSet<Parent>
. This will add the Parent
and the list with Child
items to the database.
Update the parent
So now, we add a Child
item to the list. Because the Parent
already exists we call the Update()
method on the DbContext
. This now throws the Microsoft.EntityFrameworkCore.DbUpdateConcurrencyException
because the new Child
item does not exist, so it can not be updated.
In Entity Framework version 3.0, there was a breaking change, which is causing this issue. Of course, you can write your own Update
method, but there is a second way to solve this issue. On the Child
item, you need to explicitly set the value of the ID
and mark not to be generated by the database.
The updated Child
class will look like this:
public class Child
{
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public Guid? ID { get; set; }
}
When you add a Child
item to Parent
make sure you set the ID
, so something like
var child = new Child(Guid.NewGuid())
After adding the Child
to the parent, you can call DbContext.Parents.Update(Parent)
to update the Parent
including the new Child
.