EF:多对多字段始终为空

时间:2012-10-29 09:37:26

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

当我尝试保存此模型时,menu.Roles字段始终为null,保存更改方法不会更改Roles字段

表格为MenuRoleMenuRole

所以,我有一对多2个模型:

菜单中有Roles个提交 角色有Menus个字段

行动方法:

    [HttpPost]
    public ActionResult Edit(Menu menu, IEnumerable<int> RoleIDs)
    {
        if (ModelState.IsValid)
        {
            var roles = _db.UserRoles.Where(rl => RoleIDs.Contains(rl.Id)).ToList();

            menu.Roles = new List<UserRole>();
            menu.Roles.AddRange(roles);

            _db.Entry(menu).State = EntityState.Modified;
            _db.SaveChanges();
            return RedirectToAction("Index");
        }
        ViewBag.ParentMenuId = new SelectList(_db.Menus, "Id", "Name", menu.ParentMenuId);
        ViewBag.RoleIDs = new SelectList(_db.UserRoles.ToList(), "Id", "Name");
        return View(menu);
    }

视图:

//...other VS auto generated fields...
<div class="editor-label">
        @Html.LabelFor(model => model.Roles, "Roles")
</div>
<div class="editor-field">
        @Html.ListBox("RoleIDs")
        @Html.ValidationMessageFor(model => model.Roles)
</div>
<p>
        <input type="submit" value="Save" />
</p>

映射:

            modelBuilder.Entity<Role>()
             .HasMany(role => role.Menus)
             .WithMany(menu => menu.Roles)
             .Map(m =>
              m.MapLeftKey("RoleId").
                 MapRightKey("MenuId").
                 ToTable("RoleMenu"));

2 个答案:

答案 0 :(得分:0)

我认为这是因为您将角色添加到菜单中,而菜单没有附加到上下文中。

尝试将代码更改为

var roles = _db.UserRoles.Where(rl => RoleIDs.Contains(rl.Id)).ToList();

_db.Attach(menu);

menu.Roles = new List<UserRole>();

menu.Roles.AddRange(roles);

_db.SaveChanges();
return RedirectToAction("Index");

答案 1 :(得分:0)

通过id从db检索它。然后问题解决了

但我认为这不是最好的解决方案

    [HttpPost]
    public ActionResult Edit(Menu menu, IEnumerable<int> RoleIDs)
    {
        var menuReal = (from m in _db.Menus.Include("Roles")
                        where m.Id == menu.Id
                        select m).FirstOrDefault();

        var roles = _db.UserRoles.Where(rl => RoleIDs.Contains(rl.Id)).ToList();

        menuReal.Roles = roles;

        _db.Entry(menuReal).State = EntityState.Modified;
        _db.SaveChanges();
        return RedirectToAction("Index");
    }