在 EntityFramework 中保存多对多

本文关键字:保存 EntityFramework | 更新日期: 2023-09-27 17:57:11

我想在编辑的列表框中显示教师和教师的所有已分配课程(多对多关系:课程、教师和课程教师)。(我想突出显示已选择的课程,如果用户更改选择,它将反映在数据库中)。

我的问题是它适用于 Get 方法,但是当我发布更新教师和相关课程时,它不会自动执行此操作(更新教师信息,但不是所选课程),尽管它在对象中分配了所有课程。

我是MVC的新手,所以我甚至不确定我的模型是否正确。但我想问题出在后期方法上。(最后一段代码,请参阅我的评论)。

需要明确的是。我已经有可用的课程列表。我只想把他们和几位老师联系起来。

到目前为止我做了什么:视图模型

public class TeacherEditor
    {
        public Teacher Teacher { get; set; }
        public int[] SelectedCourseIds { get; set; }
        public MultiSelectList Courses { get; set; }
    }

教师模式:

 public class Teacher
    {
        public int TeacherID { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public ICollection<Course> Courses { get; set; }
            public Teacher()
          {
              Courses = new HashSet<Course>();
          }
    }   

视图:

 <div class="editor-field">
                     @Html.ListBoxFor(model=>model.SelectedCourseIds, Model.Courses)
        </div>

控制器获取:

 public ActionResult Edit(int id = 0)
        {
            var teacher = db.Teachers.Include(x=>x.Courses).Where(x=>x.TeacherID==id).SingleOrDefault();
            if (teacher==null)
            {
                return HttpNotFound();
            }
            var selectedCourses = teacher.Courses.Select(x=>x.CourseID);
            var model = new TeacherEditor
            {
                Teacher = teacher,
                Courses = new MultiSelectList(db.Courses, "CourseID", "Name", selectedCourses),
                SelectedCourseIds = selectedCourses.ToArray()
            };
            if (model == null)
            {
                return HttpNotFound();
            }
            return View(model);
        }     

控制器开机自检:

 [HttpPost]
        public ActionResult Edit(TeacherEditor teacherEditor)
        {
            if (ModelState.IsValid)
            {
                    foreach (var id in teacherEditor.SelectedCourseIds)
                    {
                        Course course = db.Courses.Where(x=>x.CourseID==id).SingleOrDefault();
                        teacherEditor.Teacher.Courses.Add(course); //Here I'm adding courses back to Teacher object for save.
                    }
                db.Entry(teacherEditor.Teacher).State = EntityState.Modified; /?This doesn't save records to my relationship table. Why?
                db.SaveChanges();
                return RedirectToAction("Index");
            }
            return View(teacherEditor);
        }

在 EntityFramework 中保存多对多

您的问题是您无法在 POST 上绑定到 MVC 中的接口(ICollection)。DefaultModelBinder 不支持绑定到抽象基类和接口。 将ICollection<Course> Courses更改为像 List<Course> Courses 这样的具体实现。

然后,您可以在视图中使用索引表示法表示课程,ListBoxFor 应该处理这个问题。

尝试类似操作:

public class Teacher
    {
        public int TeacherID { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public IQueryable<Course> Courses { get; set; }
        public Teacher()
        {
            Courses = new IQueryable<Course>();
        }
    } 
public class TeacherEditor
    {
        public Teacher Teacher { get; set; }
        public int[] SelectedCourseIds { get; set; }
        public List<Course> CourseList 
        {
            get { return Teacher.Courses.ToList(); }
            set { Teacher.Courses = value.ToList(); }
        }
    }