具有多对多关系的 ASP.net MVC4 多选列表框

我是 ASP.net、MVC4 和 EF 的新手,在从相对简单的样本到更复杂的东西(只是稍微)的飞跃方面遇到了麻烦。我已经为这里的问题简化了我的模型,因此请考虑以下内容。如果我有一些不正确的术语,请原谅我。

我有一个 Employee 对象和一个 Division 对象。一个员工可以属于多个部门,一个部门可以有多个员工。

public class Employee
{
    public int EmployeeId { get; set; }
    public String FirstName { get; set; }
    public String LastName { get; set; }

    public virtual ICollection<Division> Divisions { get; set; }
}

public class Division
{
    public int DivisionId { get; set; }
    public String DivisionName { get; set; }

    public virtual ICollection<Employee> Employees { get; set; }
}

我通过以下方式将这些映射到上下文文件中:

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {

        modelBuilder.Entity<Employee>()
                .HasMany(e => e.Divisions)
                .WithMany(d => d.Employees)
                .Map(m =>
                {
                    m.ToTable("EmployeesDivisionsId");
                    m.MapLeftKey("EmployeeId");
                    m.MapRightKey("DivisionId");
                });      
    }

对于我的视图控制器,我有以下内容。我已经为多对一关系使用了 ViewBag(多么好的名字)并且它们运行良好,所以我正在尝试修改它以与这里的多对多一起使用:

    public ActionResult Index()
    {
        return View(db.Employees).ToList());
    }

    //
    // GET: /Employees/Details/5

    public ActionResult Details(int id = 0)
    {
        Employee employee = db.Employees.Find(id);
        if (employee == null)
        {
            return HttpNotFound();
        }
        return View(employee);
    }

    //
    // GET: /Employees/Create

    public ActionResult Create()
    {
        ViewBag.Divisions = new MultiSelectList(db.Divisions, "DivisionId", "DivisionName");

        return View();
    }

    //
    // POST: /Employees/Create

    [HttpPost]
    public ActionResult Create(Employee employee)
    {
        ViewBag.Divisions = new MultiSelectList(db.Divisions, "DivisionId", "DivisionName");

        if (ModelState.IsValid)
        {
            db.Employees.Add(employee);
            db.SaveChanges();
            return RedirectToAction("Index");
        }

        return View(employee);
    }

最后在编辑视图中,我有以下代码。再次对于多对一关系,一个简单的 DropDownList 可以与控制器中的 ViewBag 一起正常工作,并且使用这种多对多多选/ListBox 方法,“Divisions”会显示在视图中,但是当点击 Save 按钮时,验证'1, 2' is not valid 显示。

    <div class="editor-label">
        @Html.LabelFor(model => model.Divisions)
    </div>
    <div class="editor-field">
        @Html.ListBox("Divisions")
        @Html.ValidationMessageFor(model => model.Divisions)
    </div>

据我了解,“分区”列表正在从数据库中正确获取并在视图中正确选择,但是当保存到数据库时,不会通过映射关系进行关联。

所以我的问题是:如何使这项工作在我保存时将正确的“部门”保存给员工?

另外,我听说人们不喜欢使用 ViewBags,有没有(更好的?)替代方式?

stack overflow ASP.net MVC4 Multiselect ListBox with Many-to-Many relationship
原文答案

答案:

作者头像

This answer maybe a bit late. However, here's one or two things that might be helpful to others finding this question.

You are using ListBox() instead of ListBoxFor() so the data isn't being automatically bound to your model. So in your controller you need:

[HttpPost]
public ActionResult Create(Employee employee, string[] Divisions)
{
    // iterate through Divisions and apply to your model
    ...
}