Dmytro Tsiniavskyi Dmytro Tsiniavskyi - 3 months ago 17
C# Question

How to remove child one to many related records in EF code first database?

Well, I have one-to-many related model:

public class Parent
{
public int Id { get; set; }
public string Name { get; set; }
public ICollection<Child> Children { get; set; }
}

public class Child
{
public int Id { get; set; }
public string ChildName { get; set; }
}


What I want to do is clear
Parent.Children
and remove related child entities from database. I've already tried:

Database context class:

modelBuilder.Entity<Parent>()
.HasMany(p => p.Children)
.WithOptional()
.WillCascadeOnDelete(true);


this works fine, but I still have redundant records in database with
Parent_Id = null
fields when I do

parent.Children.Clear();
repository.InsertOrUpdate(parent);


in my repository class. Also the same behavior is when I do:

modelBuilder.Entity<Parent>()
.HasMany(pr => pr.Children)
.WithOptional(ri => ri.Parent)
.WillCascadeOnDelete(true);


with additional
Parent
property in
Child
class

public class Child
{
...
public Parent Parent { get; set; }
...
}


or when I do

modelBuilder.Entity<Child>()
.HasOptional(p => p.Parent)
.WithMany(p => p.Children)
.HasForeignKey(p => p.Parent_Id)
.WillCascadeOnDelete(true);


with additional Parent_Id property in
Child
class

public class Child
{
...
public int Parent_Id { get; set; }
...
}


So, how can I configure cascade deleting correctly? Or how should I supposed to remove those child entities? I assume this is casual task but I'm just missing something.

Answer

Cascading delete has no effect here because you don't delete the parent but just call InsertOrUpdate. The correct procedure is to delete the children one-by-one, like so for example:

using (var context = new MyContext())
{
    var parent = context.Parents.Include(p => p.Children)
        .SingleOrDefault(p => p.Id == parentId);

    foreach (var child in parent.Children.ToList())
        context.Children.Remove(child);

    context.SaveChanges();
}