我无法更新多对多关系。当我调试" 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);
}
答案 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从数据库中选择新教师。您永远不应该直接保存已发布的实体。然后,新代码会删除取消选择的技能并添加新选择的技能。