How to cascade delete in entity framework? - c#

I have two objects in my model
Car and carPart
with 1:n relationship.
I want to delete cascade the entity car.
when I delete i get the following exception :
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.
I think it tries to delete the car object first and then the car parts.
Which is imposiible due to the foreign key.
How do I handle this ?
I want, obviously to delete the carPart first and then only the car.
Thanks.

You'll need to tell the database that you want to cascade on delete, and then Entity Framework will do what you expect. You can change the FK behavior if you go to the Relationships screen for a table in SQL Server Management Studio:

If you want Cascade delete then setup cascade delete at database level. You are getting error because SQL is not allowing to deletion.
You don't have to do it in Entity Framework.

Related

Prevent set null on delete in Entity Framework database-first

I have a database-first model using Entity Framework 6.2.0 which has the following association:
As you see, the OnDelete property on both ends is set to None. The corresponding relation in SQL server is shown below:
Although there is no explicit setting to set null on delete, when I try to remove an object from Plannings (primary table), EF sets all foreign key records in the table Waybill to null.
In the same database and model, I have the following foreign key and corresponding association:
All circumstances are the same as earlier. But in this case, when I try to remove an object from Products, it fails because of conflict with foreign key constraint (as I expect).
Why these two similar cases have different behavior? How can I completely disable set null on delete in my database-first model? I know that in code-first model, we can delete conventions using the following:
modelBuilder.Conventions.Remove<ManyToManyCascadeDeleteConvention>();
modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
But I could not find any way to do this in database-first.

Updating detached EF object with many to many mapping

I have a repository in EF that needs to Update detached entities but ones which exist in the ObjectStateManager. Imagine you have a session open on a DBContext where you have loaded a particular entity, but then you receive a request to update from a detached version of the object. The only way I have found to do this is to GET the existing object in the state manager, then one by one, update the fields to the fields of the passed-in object. Then set the state of the object state manager version to modified, and save the context.
This works for simple entities that don't contain navigation properties.
I am now trying to do so on an entity that has a many-to-many relationship.
Imagine you have a BlogPost object, and a Hashtag object. This is a many to many relationship. I have defined this and in the database I can see I have three tables, the BlogPost, the HashTag and the mapping table.
What I want to be able to do is edit the blog post on the front end, pass in the updated blog post with it's new list of hashtags that apply to it, and update the database.
The problem is the list of hashtags could be completely unrelated to the old one, so I first have to clear out all the previous mappings, then add the new ones in. If they are the same, this will be a necessary redundancy but the only way to achieve it.
I cannot figure out how to clear out the previous mappings in the many to many relationship though. I have tried
foreach (var tag in dbBlogPost.Hashtags)
dbItem.Hashtags.Remove(tag);
I then add the new hashtags to the empty collection, then do
Work.Context.Entry(dbItem).State = EntityState.Modified;
Work.Context.Save();
But when I save the repository, I get the following exception
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.
Can anyone suggest what I am doing wrong?
The DbSet<TEntity>.Local represents a local view of all Added, Unchanged, and Modified entities in this set. So you can clear all the collection before make any change.
dbBlogPost.Hashtags.Local.Clear();

Deleting Entity with OneToMany Relationship With Another Entity

I have two tables. These are Design and Like. One design can have many likes and one like should be related to one Design.
When I try to delete a Design it throws me an exception:
The DELETE statement conflicted with the REFERENCE constraint
"FK_dbo.DesignLike_dbo.Design_DesignId". The conflict occurred in
database "XXXDB", table "dbo.DesignLike", column 'DesignId'. The
statement has been terminated.
modelBuilder.Entity().HasMany(x => x.Likes).WithRequired(x => x.Design).WillCascadeOnDelete(false);
I dont even try to delete related entities ? Why I get this exception ?
You are trying to delete an object that still has child objects. And the foreign key on the child objects will give you this exception.
You should decouple the child objects are link them to another parent before deleting the current one. Or include them in a cascaded delete.
In your case the design you are trying to delete has at least one like with the foreign key set to the id of your design. When you now delete the design and cascading is off it will violate the foreign key constraint of your like.
It sounds like you've set up your database to enforce a valid foreign key constraint on the DesignId column in your DesignLike table.
If you try and delete a Design, you're deleting the DesignId which is referenced by all the DesignLikes as a foreign key. If you were allowed to do that, you'd find your database in an inconsistent state - your foreign key wouldn't really have meaning if there isn't a guarantee it references a valid record.
You could either remove the now invalid foreign key from your child objects, or set add a Deleted / Visible flag to your Design if you wish keep the Design and corresponding DesignLikes

Delete Item from DB using EntityCollection.Remove()

I have master table and details table. For example master table is ObjectSet<'MasterObject> and details table is ObjectSet<'DetailObject>. So each MasterObject contains EntityCollection<'DetailObject>.
As I understand I can remove DetailObject from database using following:
EntityCollection<'DetailObject> ec = masterObject.DetailObjects;
// as navigation property
ec.Remove(deleting_detail_object); // deleting_detail_object will be removed and marked for deleting.
context.SaveChanges(); // I have exception
After Remove() the deleting_detail_object.MasterObject (navigation property) is null. It is normal. But context.SaveChanges() give me following exception :
"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."
I can delete this DetailObject using context.RemoveObject(), but is it possible to do it using EntityCollection<>?
I do not think this problem has something to do with EntityCollection, I think you have a problem with your database schema.
If your master table have a FK to details that is not nullable you cannot remove the detail table row since that would violate your database schema.
Either change it so that the FK can be null or redesign your database schema.
If this is an operation you need to support, maybe you should have a FK in your details table referencing your master table. So, that you can delete detail rows.
If this does not help please supply a script that shows how you create your database tables.

Entityframework 4: Problem with ForeignKey when removing a child entity from parents collection

New to the EF, I have an issue.
OK, so, I have an Entity with a related Table (one-to-many relationship). The entity holds a collection of child objects from the related table. I want to remove an object from the related collection but not from the child table.
However, when I call <entity>.myRelatedChildTable.Remove( childEntity ) and then call the _context.SaveChanges( ), I get an exception about ForeignKey Constraints. Now, if I call the _context.DeleteObject() and then _context.SaveChanges() we have no problem. But, now we have no child entity as well--it is deleted from the db.
here is the text of the Exception:
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.
anyone have an idea/suggestion how I can fix this?
It sounds like you're basically trying to decouple EF from the database. Unfortunately save changes pushes the changes back to the database which obviously you don't want. You can just not call SaveChanges and continue to work with the collection. EF will account for your deletion and not return that information. At the end you can discard your changes and move on.
If you do actually want to delete the item without deleting the child you can't in the current schema. You would have to allow nulls in the DB.

Categories

Resources