在EntityFramework中保存多对多

时间:2013-02-03 20:17:47

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

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

我的问题是它适用于Get方法,但是当我发布更新教师和相关课程时,它不会自动执行(更新教师信息,但不会选择课程),尽管它已经分配了所有课程宾语。

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

要清楚。我已经有了一系列课程。我只想将他们与几位老师联系起来。

到目前为止我做了什么:ViewModel

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>

控制器GET:

 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);
        }     

控制器POST:

 [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);
        }

1 个答案:

答案 0 :(得分:3)

您的问题是您无法在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(); }
        }
    }