MVC EF数据库首先是多对多

时间:2015-08-20 11:30:27

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

有人可以首先澄清EF数据库中有多少关系。 例如StudentCourse表,其中关系是多对多的。我已经有了一个数据库。

所以我创建了一个.edmx

StudentCourses的类是自动创建的。我添加了一个名为StudentCourseViewModel.cs的新类。想法是控制与它的关系。 我的StudentCourseViewModel包含以下内容:

public class StudentCourseViewModel
{
    public Student Student{ get; set; }
    public IEnumerable<SelectListItem> AllCourses{ get; set; }    
    private List<int> _selectedCourse;
    public List<int> SelectedCourse
    {
        get
        {
            if (_selectedCourse == null)
            {
                _selectedCourse = Student.Courses.Select(m => m.pkID).ToList();
            }
            return _selectedCourse;
        }
        set { _selectedCourse = value; }
}

public ActionResult Create()
{
    ViewBag.Courses = new SelectList(db.Courses, "pkID", "Name"); 
    return View();
}

public ActionResult Create(StudentCourseViewModel model,[Bind(Include = "pkID,Name")] Student student)
{
    if (ModelState.IsValid)
    {
        if (student == null)
            return HttpNotFound();

        // Remove items that were unselected
        db.Courses.Where(m => !model.SelectedCourses
            .Contains(m.pkID))
            .ToList()
            .ForEach(m => student.Courses.Remove(m));

        // Add newly selected items
        var existingClientIds = student.Courses.Select(m => m.pkID).ToList();
        db.Courses.Where(m => model.SelectedCourses.Except(existingClientIds)
            .Contains(m.pkID))
            .ToList()
            .ForEach(m => student.Courses.Add(m));

        db.students.Add(student);
        db.SaveChanges();
        return RedirectToAction("Index");
    }
    return View(student);
}

我现在想如何处理// GET:/Create和// POST:/Create 以及如何查看create.cshtml中的课程列表? 我使用上面的代码得到以下错误:

  

类型&#39; System.Data.Entity.Infrastructure.DbUpdateException&#39;的例外情况发生在EntityFramework.dll中但未在用户代码中处理

     

其他信息:更新条目时发生错误。有关详细信息,请参阅内部异常。

1 个答案:

答案 0 :(得分:1)

保存多对多关系可能有点棘手,好像你不小心,EF可能会感到困惑,并认为你正在尝试读取现有项目并给你完整性错误。

您已经在使用具有包含整数列表的属性的视图模型。这很好。赢得了一半的战斗。现在,您只需要一些逻辑来查询所选课程并将其添加到Courses集合中:

// Remove items that were unselected
db.Courses.Where(m => !model.SelectedCourse.Contains(m.Id)).ToList()
    .ForEach(m => student.Courses.Remove(m));

// Add newly selected items
var existingCourseIds = student.Courses.Select(m => m.Id).ToList();
db.Courses.Where(m => model.SelectedCourse.Except(existingCourseIds).Contains(m.Id)).ToList()
    .ForEach(m => student.Courses.Add(m));

从技术上讲,只有在您编辑现有学生时才需要这样做。使用相同的代码进行创建或编辑不应该受到影响,但是对于创建它可以简化为:

student.Courses = db.Courses.Where(m => model.SelectedCourse.Contains(m.Id));

由于您正在创建一个全新的学生,因此无需担心现有的关系。