Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How delete many-to-many relation in Entity Framework 6

I have a problem with the removal of items from the database if connects them a many to many relationship

My database look like

| [Project] | <-- | [JobInProject] | --> | [Job] |
=============     ==================     =========
| ProjectID |     | JobInProjectID |     | JobID |
|           |     | ProjectID      |     |       |
|           |     | JobID          |     |       |

Primary keys from Project and Job table are also set as foreign key in others tables but I think it isn't problem because when I remove item from Job table, it is removed correctly with all related items in others tables

All foreign keys are set by constraint and on delete cascade on update cascade

Code which I use to delete job item

 Job job = await db.Jobs.FindAsync(id);
 db.Entry(job).State = EntityState.Deleted;
 await db.SaveChangesAsync();    

and project:

Project project = await db.Projects.FindAsync(id);
db.Entry(project).State = EntityState.Deleted;
await db.SaveChangesAsync();

Code to remove project item remove only data from Project table and JobInProject table do not remove Job and related items.

When I modify code to remove Project like this:

 Project project = await db.Projects.FindAsync(id);

 foreach (var item in project.JobInProjects)
 {
     db.Entry(item.Job).State = EntityState.Deleted;
 }

 db.Entry(project).State = EntityState.Deleted;
 await db.SaveChangesAsync();

I get an error on the await db.SaveChangesAsync(); line

The operation failed: The relationship could not be changed because one or more of the foreign-key properties is non-nullable. When a change is made to a relationship, the related foreign-key property is set to a null value. If the foreign-key does not support null values, a new relationship must be defined, the foreign-key property must be assigned another non-null value, or the unrelated object must be deleted.

How can I remove Project item and related Job items ?

I will be grateful for help

like image 744
xpasd Avatar asked Mar 25 '16 10:03

xpasd


People also ask

How do I cascade delete in Entity Framework?

There are two ways to handle this situation: Change one or more of the relationships to not cascade delete. Configure the database without one or more of these cascade deletes, then ensure all dependent entities are loaded so that EF Core can perform the cascading behavior.

How do I delete data in Entity Framework?

Delete a Record In Connected Scenario, you can use the Remove or RemoveRange method to mark the record as Deleted . In Disconnected Scenario, you can attach it to the context and set its state as Deleted . Calling SaveChanges will send the delete query to the database.

What is WillCascadeOnDelete?

WillCascadeOnDelete(Boolean) Configures whether or not cascade delete is on for the relationship.


1 Answers

It's because you don't mark the JobInProject object as Deleted:

foreach (var item in project.JobInProjects)
{
    db.Entry(item.Job).State = EntityState.Deleted;
    db.Entry(item).State = EntityState.Deleted; // <= line added
}

If you don't do that, EF will assume you don't want to delete the item and try to set both foreign keys in JobInProject to null, but of course one or more of the foreign-key properties is non-nullable (both aren't).

like image 144
Gert Arnold Avatar answered Oct 19 '22 17:10

Gert Arnold