don't think outside of the box, think like there is no box

Update Entity Framework Child records

14 Dec 2020 | 5 minute read

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.

About

arjan

I work as a consultant for Xpirit. I am passionate about problem-solving for customers with the help of technology. I love to learn new techniques, technologies and ways to improve myself.

Tags