【问题标题】:MVC .Net Cascade Deleting when using EF Code First Approach使用 EF 代码优先方法时的 MVC .Net 级联删除
【发布时间】:2012-03-03 17:51:38
【问题描述】:

我对 MVC 很陌生,但在级联删除方面遇到了麻烦。对于我的模型,我有以下 2 个类:

    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 但我似乎只适用于关系是一对一的模型,所以我在这里迷路了,我到处搜索,找不到这个问题的解决方案,如果有人能指出我的意思的话我错过它会非常好:),在此先感谢,再一次,请原谅我的菜鸟,我才刚刚开始,但想解决一个大项目以便能够学到很多东西。

【问题讨论】:

    标签: .net asp.net-mvc entity-framework-4.1 ef-code-first


    【解决方案1】:

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

    您可以添加 FK 的不可为空的标量属性 (BlogId)

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

    或者使用 fluent API 进行配置

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

    【讨论】:

    • 耶! :D,谢谢它的工作!,非常感谢,我只是不知道流畅的 API,但似乎是做这些事情的好方法,顺便说一句¿我可以通过数据注释获得这种行为吗?。
    • @Q_ro 数据注释的功能集有限。
    【解决方案2】:

    不确定您要在这里做什么,但您有一个记录,因此不确定您为什么要尝试循环。这是我的删除代码:

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

    【讨论】:

    • 好吧,这样想,每个产品都有一个类别,我想在删除产品时也删除这些类别,因为就像现在一样,如果我删除一个产品,我的类别仍将存在于数据库中。
    • 是的,但是您的代码应该只显示包含类别的代码,您还应该有一个用于类别和项目的启用/禁用列,本质上您不应该真正删除任何内容,而只需将其标记为已删除,这样可以减少问题稍后引用 ID 但不再存在的位置。如果您想从对象中获取类别 ID,请删除类别,然后删除原始对象,但您确实应该编写代码以更好地处理它,而不是仅仅删除所有内容:-)
    猜你喜欢
    • 2012-02-06
    • 2014-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多