【问题标题】:Entity Framework Many To Many Relationship is adding "end" items BEFORE adding the relationship实体框架多对多关系在添加关系之前添加“结束”项
【发布时间】:2011-11-18 17:41:07
【问题描述】:

我已经使用常见的学生和课程场景建立了一个非常简单的实体框架数据库第一个项目。

  • 一个学生可以有很多课程
  • 一门课程可以有很多学生

我已经在数据库中建立了关系,并且 EF 为此创建了一个不错的多对多导航项。

问题当我向学生添加课程时,课程被重新添加到课程表中,然后关系被添加到数据库中,导致重复课程的数量不断增加

这让我发疯了,知道我做错了什么吗?

我的一些代码....

我在生成的实体上方创建了一个 Partial 类,这样我就可以拥有一个带有复选框的 EditorTemplate,这将允许用户勾选要添加的课程

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

课程的编辑器模板

@model University.Models.Course

<div>
    @Html.CheckBoxFor(m => m.isSelected)
    @Html.DisplayFor(m => m.CourseName)


    @Html.HiddenFor(m => m.CourseName)
    @Html.HiddenFor(m =>m.CourseId)
</div>

创建学生视图

@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>
}

页面的 ViewModel

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

任何帮助我指出正确的方向将不胜感激

【问题讨论】:

    标签: asp.net-mvc entity-framework


    【解决方案1】:

    在将学生添加到上下文之前,您必须在发布操作中将所选课程附加到上下文中。否则,EF 假定整个对象图(包括所有课程的学生)是新的,并且必须插入 到数据库中。通过附加(=将课程置于Unchanged 状态),您告诉 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);
    }
    

    【讨论】:

    • 听起来很明智,我会在星期一试一试!谢谢
    猜你喜欢
    • 2017-02-14
    • 1970-01-01
    • 1970-01-01
    • 2011-10-13
    • 2018-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-09
    • 1970-01-01
    相关资源
    最近更新 更多