I'm developing a website using MVC4 with EF code first approach.
I have some problems with deleting the children in entities with one to many relations.
Edit to clearify: In my Edit view, I add/remove/update existing childen in the childrens collection on the parent, add/remove is done using javascript. When I receive the updated parent in the post request in the controller method, I want to sync/update the parent and child entities in the database. The parent object is in a detached state when updated in the view. So, when I attach the parent again, I want it to do all the updates that have been done during detached state.
The entity relations are set up so that when removing a child entity from the parent collection, the child entity is also deleted from the child table (cascade delete sort of?), and this works when in attached state.
However, when attching the parent and saving the changes, only added/updated children are added/modified in the database. But removed children from the parent collection are not deleted in the database (which I want them to be).
How can this be solved??
The entities are:
class Parent
{
public virtual ICollection<Child> Children { get; set; }
}
class Child
{
public string Text { get; set; }
}
This works and will remove child from database:
void RemoveChildFromCollection()
{
// get the first parent and remove the first child in collection
var context = new DatabaseContext();
var parent = context.Parents.First();
parent.Children.Remove(parent.Children.First());
context.SaveChanges();
}
ControllerMethod: This does not work as above, removed children are not removed from the childrens table
public ActionResult Edit(Parent parent)
{
var context = new DatabaseContext();
context.Entry(parent).State = System.Data.EntityState.Modified;
context.SaveChanges();
return View();
}
The modelbuilder are setup to delete child entity from child table when removing them from parent collection
// Use Identifying relation. Define complex key for ChildObject containing both Id and
ParentObjectId
modelBuilder.Entity<Child>()
.HasKey(c => new {c.ChildID, c.ParentID});
// Because defining such key will remove default convention for auto incremented Id you must redefine it manually
modelBuilder.Entity<Child>()
.Property(c => c.ChildID)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
// Set cascade delete
modelBuilder.Entity<Parent>()
.HasMany(p => p.Children)
.WithRequired()
.HasForeignKey(c => c.ParentID)
.WillCascadeOnDelete();