ASP.net MVC实体框架更新多对多关系

本文关键字:关系 更新 框架 net MVC 实体 ASP | 更新日期: 2023-09-27 18:27:47

我无法更新多对多关系。当我调试"Response.Write(teacher.skills);"时,值看起来是正确的,但数据库没有更新对象。

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include = "id,lastname,firstname,image,campusId,skillIds")] Teacher teacher)
{
    if (ModelState.IsValid)
    {
        if (teacher.skillIds != null)
        {
            teacher.skills = (from t in db.Skills.ToList() where teacher.skillIds.Contains(t.id) select t).ToList();
        }
        Response.Write(teacher.skills);
        // 1st attempt -->
        //db.Teachers.Attach(teacher);
        //db.Entry(teacher).State = EntityState.Modified;
        // 2nd attempt -->
        UpdateModel(teacher);

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

ASP.net MVC实体框架更新多对多关系

不要清除技能。这实际上是告诉实体框架从联接表中删除所有现有关系,然后重新添加全新的关系。

更新M2M关系时,不能仅设置特性。您需要首先删除任何取消选择的项目,然后添加新项目,同时保留现有项目:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(int id, TeacherViewModel model)
{
    var teacher = db.Teachers.Find(id);
    if (teacher == null)
    {
        return new HttpNotFoundResult();
    }
    if (ModelState.IsValid)
    {
        teacher.firstname = model.lastname;
        teacher.lastname = model.lastname;
        teacher.image = model.image;
        teacher.campusId = model.campusId;
        // Remove deselected skills
        teacher.skills.Where(m => !model.skillIds.Contains(m.Id))
            .ToList().ForEach(skill => teacher.skills.Remove(skill));
        // Add new skills
        var existingSkillIds = teacher.skills.Select(m => m.Id);
        db.Skills.Where(m => model.skillIds.Exclude(existingSkillIds).Contains(m.Id))
            .ToList().ForEach(skill => teacher.skills.Add(skill));
        db.SaveChanges();
        return RedirectToAction("Index");
    }
    return View(model);
}

正如您所看到的,我添加了一个视图模型,您应该随时使用它来添加Bind。只是永远不要使用Bind。我还将教学id作为URL的一部分进行传递。你永远都不应该发布id。永远不要在你的帖子正文中包含任何你不想被潜在修改的内容。我用这个id从数据库中选择新的老师。您永远不应该直接保存已发布的实体。然后,有一个新的代码,它删除了取消选择的技能,并添加了新选择的技能。