Asp.net mvc 实体框架多对多关系添加了;完";添加关系之前的项目
我已经建立了一个非常简单的实体框架数据库第一个项目,使用普通学生和课程场景Asp.net mvc 实体框架多对多关系添加了;完";添加关系之前的项目,asp.net-mvc,entity-framework,Asp.net Mvc,Entity Framework,我已经建立了一个非常简单的实体框架数据库第一个项目,使用普通学生和课程场景 一个学生可以有很多课程 一门课程可以有很多学生 我已经在数据库中建立了关系,EF为此创建了一个很好的多对多导航项 问题当我向学生添加课程时,课程会重新添加到课程表中,然后关系会添加到数据库中,导致重复课程的数量不断增加 这让我快发疯了,知道我做错了什么吗 我的一些代码 我在实体生成的基础上创建了一个分部类,这样我就可以有一个带有复选框的EditorTemplate,这将允许用户勾选要添加的课程 public part
- 一个学生可以有很多课程
- 一门课程可以有很多学生
public partial class Course
{
public bool isSelected { get; set; }
}
public partial class Course
{
public Course()
{
this.Students = new HashSet<Student>();
}
public int CourseId { get; set; }
public string CourseName { get; set; }
public virtual ICollection<Student> Students { get; set; }
}
如果您能为我指出正确的方向,我们将不胜感激。在将学生添加到上下文之前,您必须在您的post操作中将所选课程附加到上下文中。否则,EF假设整个对象图(包括所有课程的学生)是新的,必须插入到数据库中。通过附加(=将课程置于<代码>未更改代码>状态),您告诉EF您不希望附加课程作为新行插入,而只希望在新学员和现有课程之间创建关系:
[HttpPost]
public ActionResult Create(CreateStudentViewModel model)
{
if (ModelState.IsValid)
{
model.student.Courses =
model.courses.Where(m => m.isSelected == true).ToList();
foreach (var course in model.student.Courses)
db.Courses.Attach(course);
// now each course is in state Unchanged in the context
db.Students.Add(model.student);
// model.student is in state Added in the context
// but the courses still have the state Unchanged.
// Without the attach-loop above they would be in
// state Added as well, which will create new courses
// in the DB after SaveChanges
db.SaveChanges();
return RedirectToAction("Index");
}
return View(model);
}
听起来很有道理,我会在周一试一试!非常感谢。
@model University.Models.CreateStudentViewModel
@using (Html.BeginForm()) {
@Html.ValidationSummary(true)
<fieldset>
<legend>Student</legend>
<div class="editor-label">
@Html.LabelFor(model => model.student.Name)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.student.Name)
@Html.ValidationMessageFor(model => model.student.Name)
</div>
<div>
@Html.EditorFor(m=>m.courses)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
public class CreateStudentViewModel
{
public Student student { get; set; }
public ICollection<Course> courses { get; set; }
}
public ActionResult Create()
{
CreateStudentViewModel vm = new CreateStudentViewModel();
vm.courses = db.Courses.ToList();
return View(vm);
}
[HttpPost]
public ActionResult Create(CreateStudentViewModel model)
{
if (ModelState.IsValid)
{
model.student.Courses = model.courses.Where(m => m.isSelected == true).ToList();
db.Students.Add(model.student);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(model);
}
[HttpPost]
public ActionResult Create(CreateStudentViewModel model)
{
if (ModelState.IsValid)
{
model.student.Courses =
model.courses.Where(m => m.isSelected == true).ToList();
foreach (var course in model.student.Courses)
db.Courses.Attach(course);
// now each course is in state Unchanged in the context
db.Students.Add(model.student);
// model.student is in state Added in the context
// but the courses still have the state Unchanged.
// Without the attach-loop above they would be in
// state Added as well, which will create new courses
// in the DB after SaveChanges
db.SaveChanges();
return RedirectToAction("Index");
}
return View(model);
}