ASP.net MVC4 Multiselect ListBox具有多对多关系

时间:2012-10-10 03:18:39

标签: entity-framework data-binding razor asp.net-mvc-4

我是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");
                });      
    }

对于我的View Controller,我有以下内容。我已经使用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一起正常工作,并且使用多对多multlectlect / ListBox方法,“Divisions”显示在视图中,但是当点击Save按钮时,验证显示'1,2'无效。

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

据我所知,“Divisions”列表正在从数据库中正确获取并在视图中正确选择,但在保存到数据库时,未通过映射关系进行关联。

所以我的问题是: 如何保存,将正确的“部门”保存到员工?

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

1 个答案:

答案 0 :(得分:0)

这个答案可能有点晚了。但是,这里有一两件可能有助于其他人发现这个问题的事情。

您正在使用ListBox()而不是ListBoxFor(),因此数据不会自动绑定到您的模型。因此,在您的控制器中,您需要:

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