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);
}
不要清除技能。这实际上是告诉实体框架从联接表中删除所有现有关系,然后重新添加全新的关系。
更新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从数据库中选择新的老师。您永远不应该直接保存已发布的实体。然后,有一个新的代码,它删除了取消选择的技能,并添加了新选择的技能。