2012-02-11 48 views
11

我对MVC非常陌生,并且遇到了级联删除的麻烦。对于我的I型以下2类:使用EF Code First Approach时MVC .Net Cascade删除

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; } 

    } 

而对于我的控制器我把他下面的删除后回:

[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"); 
} 

问题是,它不会工作无论什么; I read this post但我似乎只适用于模型的关系是一对一的,所以我迷失在这里,我到处搜索,并找不到解决方案,如果有人能指出我缺少的东西这将是非常好的:),在此先感谢,并再次,原谅我的nooobness我刚刚开始,但想要解决一个大项目,能够学到很多东西。

回答

15

这是因为EF在默认情况下不强制执行级联删除为可选关系。模型中的关系被推断为可选。

您可以添加的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; } 
} 

不可为空的标量属性(BlogId),或配置该用流利的API

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

耶! :D,谢谢它的工作!,非常感谢,我只是不知道流利的API,但似乎是一个很好的方式来做这件事情,顺便说一句,我可以得到这种行为与数据注释?。 – 2012-02-11 16:44:47

+0

@Q_ro数据注释具有有限的一组功能。 – Eranga 2012-02-12 00:43:02

1

不知道你想在这里做,但你有一个记录,因此不知道为什么你试图循环这里是我的删除代码:

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"); 
      } 
    } 
+0

好了,这样一来,每个产品想起来了,有一个类别,我想删除这些类别,当我删除产品,'因为,因为它是现在,如果我删除产品,我的类别仍然会在数据库中。 – 2012-02-11 16:34:23

+0

是的,但你的代码应该只显示包含类别的代码,你还应该有一个类别和项目的启用/禁用列,基本上你不应该真的删除任何东西,但只是标记为删除,不复存在。如果你想要,虽然你可以从对象中获得类别ID,但删除该类别,然后删除原始对象,但你应该真的编写代码来更好地处理它,而不仅仅是删除所有内容:-) – davethecoder 2012-02-11 16:42:20

+0

感谢您的建议,我会记住这一点:)。 – 2012-02-11 17:05:45