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

时间:2015-12-22 11:01:58

标签: c# asp.net asp.net-mvc entity-framework

我无法更新多对多关系。当我调试" 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);
}

1 个答案:

答案 0 :(得分:3)

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

更新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从数据库中选择新教师。您永远不应该直接保存已发布的实体。然后,新代码会删除取消选择的技能并添加新选择的技能。