2

編集時にリストボックスに教師と教師に割り当てられたすべてのコースを表示したい(多対多の関係:Course、Teacher、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);
        }
4

1 に答える 1

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(); }
        }
    }
于 2013-02-03T21:51:29.653 に答える