3

How can I implement Cascade Delete in a self referencing table in EF Core 2 (code first)?

(For example there is a Comment Table and man can reply to a comment and this reply can reply by another.)

public class Comment
{
    public virtual int Id { get; set; }
    public virtual int? ParentId { get; set; }
    public Comment Parent { get; set; }
    public virtual IList<Comment> Replies { get; set; }
    public virtual string Description { get; set; }
    public virtual Article Article { get; set; }
}

enter image description here

Ivan Stoev
  • 195,425
  • 15
  • 312
  • 343
x19
  • 8,277
  • 15
  • 68
  • 126
  • 1
    Shortly - you can't. It's not really EF limitation, but MS SqlServer limitation, hence applied to all MS developed frameworks, including EF (Core). You have to turn cascade deled off (which I think is by default for this type of relationship) and delete the related records by hand or using database trigger. – Ivan Stoev Mar 10 '18 at 17:26
  • For one-to-many there is a solution. Most probably, there should be a solution.(http://mrshipley.com/2016/04/24/enabling-cascade-delete-in-ef-core-using-the-fluent-api-code-first/) public class MyDBContext : DBContext { public DbSet Blog { get; set; } public DbSet Posts { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity() .HasOne(p => p.Blog) .WithMany(b => b.Posts) .OnDelete(DeleteBehavior.Cascade); } } – x19 Mar 10 '18 at 23:35

1 Answers1

6

The problem solved by recursive method:

[HttpPost]
public async Task<JsonResult> DeleteComment([FromBody] DeleteCommentViewModel obj)
{
    if (ModelState.IsValid)
    {
       var comment = await 
      _commentRepository.GetAll().SingleOrDefaultAsync(m => m.Id == obj.CommentId);
      if (comment != null)
      {
          await RemoveChildren(comment.Id);
         _commentRepository.Delete(comment);
      }
      if (Request.IsAjaxRequest())
      {
          return Json(1);
      }
   }
   return Json(new { code = 0 });
}


async Task RemoveChildren(int i)
{
    var children = await _commentRepository.GetAll().Where(c => c.ParentId = i).ToListAsync();
        foreach (var child in children)
    {
       await RemoveChildren(child.Id);
       _commentRepository.Delete(child);
    }
}
x19
  • 8,277
  • 15
  • 68
  • 126