加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

asp.net-mvc – 实体框架4不保存我的多对多行

发布时间:2020-12-15 22:43:26 所属栏目:asp.Net 来源:网络整理
导读:希望是一个非常简单的问题.但是我正在使用一个MVC应用程序的Code First,并且我有一个具有多对多关系的Category和ServiceType对象: public class Category{ public Category() { ServiceTypes = new HashSetServiceType(); } public Guid CategoryId { get;
希望是一个非常简单的问题.但是我正在使用一个MVC应用程序的Code First,并且我有一个具有多对多关系的Category和ServiceType对象:
public class Category
{
    public Category()
    {
        ServiceTypes = new HashSet<ServiceType>();
    }

    public Guid CategoryId { get; set; }

    [Required(ErrorMessage = "Name is required")]
    public string Name { get; set; }

    public virtual ICollection<ServiceType> ServiceTypes { get; set; }
}

数据库已正确生成,并包含名为CategoryServiceTypes的链接表.我的问题是我将项目添加到我的ServiceTypes集合并调用save,虽然没有发生错误,但是没有行添加到CategoryServiceTypes.当以下代码到达SaveChanges时,category.ServiceTypes的计数为1,所以在集合中肯定有一些东西:

[HttpPost]
    public ActionResult Edit(Category category,Guid[] serviceTypeIds)
    {
        if (ModelState.IsValid)
        {
            // Clear existing ServiceTypes
            category.ServiceTypes.Clear();

            // Add checked ServiceTypes
            foreach (Guid serviceType in serviceTypeIds)
            {
                ServiceType st = db.ServiceTypes.Find(serviceType);
                category.ServiceTypes.Add(st);
            }

            db.Entry(category).State = EntityState.Modified;
            db.SaveChanges();
            return RedirectToAction("Index");
        }
        return View(category);
    }

我希望我在这里做明显的错误.有任何想法吗?

谢谢.

编辑:

虽然以下回应确实是正确的答案,我以为我会添加以下最后版本的编辑帖子方法:

[HttpPost]
    public ActionResult Edit(Category category,Guid[] serviceTypeIds)
    {
        if (ModelState.IsValid)
        {
            // Must set to modified or adding child records does not set to modified
            db.Entry(category).State = EntityState.Modified;

            // Force loading of ServiceTypes collection due to lazy loading
            db.Entry(category).Collection(st => st.ServiceTypes).Load(); 

            // Clear existing ServiceTypes
            category.ServiceTypes.Clear();

            // Set checked ServiceTypes
            if (serviceTypeIds != null)
            {
                foreach (Guid serviceType in serviceTypeIds)
                {
                    ServiceType st = db.ServiceTypes.Find(serviceType);
                    category.ServiceTypes.Add(st);
                }
            }

            db.SaveChanges();
            return RedirectToAction("Index");
        }
        return View(category);
    }

注意强制加载ServiceTypes集合的行,这是需要的,因为延迟加载不包括那些子项,这意味着清除ServiceTypes集合什么都不做.

解决方法

尝试将您将类别附加到行前面的循环前面的上下文:
[HttpPost]
public ActionResult Edit(Category category,Guid[] serviceTypeIds)
{
    if (ModelState.IsValid)
    {
        // Clear existing ServiceTypes
        category.ServiceTypes.Clear();
        db.Entry(category).State = EntityState.Modified;
        // category attached now,state Modified

        // Add checked ServiceTypes
        foreach (Guid serviceType in serviceTypeIds)
        {
            ServiceType st = db.ServiceTypes.Find(serviceType);
            // st attached now,state Unchanged
            category.ServiceTypes.Add(st);
            // EF will detect this as a change of category and create SQL
            // to add rows to the link table when you call SaveChanges
        }

        db.SaveChanges();
        return RedirectToAction("Index");
    }
    return View(category);
}

在您的代码中,EF不会注意到您已经添加了服务类型,因为当servicetypes已经在category.ServiceTypes集合中并且所有服务类型已经被附加到上下文中时,将类别附加到上下文.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读