Q_ro
Q_ro

Reputation: 433

MVC .Net Cascade Deleting when using EF Code First Approach

I'm pretty new to MVC and i'm having troubles with cascade deleting. For my model I the following 2 classes:

    public class Blog
    {
        [Key]
        public int Id { get; set; }
        [Required]
        public string Name { get; set; }
        [DisplayFormat()]
        public virtual ICollection<BlogEntry> BlogEntries { get; set; }
        public DateTime CreationDateTime { get; set; }
        public string UserName { get; set; }
    }

    public class BlogEntry
    {
        [Key]
        public int Id { get; set; }
        [Required]
        public string Title { get; set; }
        [Required]
        public string Summary { get; set; }
        [Required]
        public string Body { get; set; }
        public List<Comment> Comments { get; set; }
        public List<Tag> Tags { get; set; }
        public DateTime CreationDateTime { get; set; }
        public DateTime UpdateDateTime { get; set; }
        public virtual Blog ParentBlog { get; set; }

    }

And for my controller I set he following on delete post back:

[HttpPost, ActionName("Delete")]
public ActionResult DeleteConfirmed(int id)
{
    Blag blog = db.Blogs.Find(id);

    foreach (var blogentry in blog.BlogEntries)
    {
        //blogentry = db.BlogEntries.Find(id);
        db.BlogEntries.Remove(blogentry);
    }
    db.Blogs.Remove(blog);
    db.SaveChanges();
    return RedirectToAction("Index");
}

Problem is it wont work no matter what; I read this post but i seem to only work for models where the relation is one to one, so i'm lost here, i have search everywhere, and can't find the solution for this problem, if some could point out what i'm missing it would be really nice :), thanks in advance, and again, pardon my nooobness i'm just getting started, but wanted to tackle a big project to be able to learn a lot.

Upvotes: 11

Views: 12964

Answers (2)

davethecoder
davethecoder

Reputation: 3932

Not sure what you are trying to do here, but you have one record so not sure why you are trying to loop. Here is my delete code:

public ActionResult Delete(int id)
{
    try {
        Products products = context.Products.Single(x => x.productId == id);
        return View(products);
    }
    catch (Exception ex)
    {
        ModelState.AddModelError("", ex.Message);
        CompileAndSendError(ex);
        return View(new Products());
    }
}

//
// POST: /Products/Delete/5

[HttpPost, ActionName("Delete")]
public ActionResult DeleteConfirmed(int id)
{
    try {
        Products products = context.Products.Single(x => x.productId == id);
        context.Products.Remove(products);
        context.SaveChanges();
        return RedirectToAction("Index");
    }
    catch (Exception ex)
    {
        ModelState.AddModelError("",ex.Message);
        CompileAndSendError(ex);
        return RedirectToAction("Index");
    }
}

Upvotes: 1

Eranga
Eranga

Reputation: 32447

That is because EF by default does not enforce cascade deletes for optional relationships. The relationship in your model is inferred as optional.

You can add a non nullable scalar property(BlogId) of the FK

public class BlogEntry
{
    [Key]
    public int Id { get; set; }
    [Required]
    public string Title { get; set; }
    [Required]
    public string Summary { get; set; }
    [Required]
    public string Body { get; set; }
    public List<Comment> Comments { get; set; }
    public List<Tag> Tags { get; set; }
    public DateTime CreationDateTime { get; set; }
    public DateTime UpdateDateTime { get; set; }

    public int ParentBlogId { get; set; }

    public virtual Blog ParentBlog { get; set; }
}

Or configure this using fluent API

   modelBuilder.Entity<BlogEntry>()
            .HasRequired(b => b.ParentBlog)
            .WithMany(b => b.BlogEntries)
            .WillCascadeOnDelete(true);

Upvotes: 16

Related Questions