EF Core - Error "The association between entities has been severed" while deleting child entity from parent

Viewed 1906

I have two entities shown below:

public class LiftPlan
{
    public int Id { get; set; }
    public ICollection<PlanConsiderationEntity> PlanConsiderations { get; set; }    
}

public class PlanConsideration
{
    public int Id { get; set; }

    public int PlanId { get; set; }
    public LiftPlan LiftPlan { get; set; }
}

The relationship is configured with -

builder
    .HasOne(e => e.LiftPlan)
    .WithMany(e => e.PlanConsiderations)
    .HasForeignKey(e => e.PlanId)
    .OnDelete(DeleteBehavior.NoAction);

It works when I add child entity like -

LiftPlan.PlanConsiderations.Add(planConsideration)

But when I try to remove child entity like

LiftPlan.PlanConsiderations.Remove(planConsideration)

it gives me the error -

The association between entities 'LiftPlanEntity' and 'PlanConsiderationEntity' with the key value '{PlanId: 1}' has been severed but the relationship is either marked as 'Required' or is implicitly required because the foreign key is not nullable. If the dependent/child entity should be deleted when a required relationship is severed, then setup the relationship to use cascade deletes.

I tried using -

dbContext.PlanConsiderations.Remove(planConsideration)

and it worked using dbContext.

I am not sure why this is happening. It should work as we are not deleting parent. If we were deleting parent then this error make sense. But for child deletion it should not happen.

Note:
I know by setting relationship to cascade deletes or making foreign key as null will work but I don't want to do that.

2 Answers

The problem is that when you remove a PlanConsideration from LiftPlan, the PlanId would need to be removed from the given PlanConsideration, but the int PlanId property is non-nullable, so this is not possible.

And when you delete a PlanConsideration from context.PlanConsiderations, that works because that scenario doesn't exhibit the problem mentioned above.

If you change int PlanId to int? PlanId (and update the db schema of course), it should work fine without throwing any errors.

The one thing I don't quite understand is this:

Note: I know by setting relationship to cascade deletes or making foreign key as null will work but I don't want to do that.

If you mean that you want to keep that foreign key non-nullable, forcing it to reference a LiftPlan, I'm not sure how could that work. I'm fairly confident that from EF Core's perspective that's the same relationship, which needs to be represented in both ways as long as you have those explicit properties present on the entities. But maybe someone will correct me on this.


If I didn't tell you anything new, let me know, so I could delete the answer. :)

I have the same situation. I don't want to cascade deletes. As a precaution, I want to force the user to delete all children before he can delete the parent. The relationship is setup like so:

.OnDelete(DeleteBehavior.ClientSetNull)

In theory, this shouldn't prevent us from deleting a child. But when I remove a child entity from the collection on the parent entity and then try to save changes, I get the exception about a severed relationship.

It works fine if you remove the child entity from the DbSet of the DbContext.

myContext.Children.Remove(myChild);

The documentation mentions this issue:

You can remove a relationship by setting a reference navigation to null, or removing the related entity from a collection navigation.

Removing a relationship can have side effects on the dependent entity, according to the cascade delete behavior configured in the relationship.

See this answer for details.

Related