回调时,实体框架没有为我提供ID

时间:2015-09-11 15:38:32

标签: entity-framework

我正在使用带有ViewModel(.on()集合的ViewModel(RoleVM)来处理此特定编辑视图。该视图显示RolePermissionVM字段以及RoleVM的复选框列表。复选框列表中的每一行都有一个RolePermissionVM作为hiddenFor的ID。

当我保存表单时,我的控制器正确地将数据写入数据库,添加或更新记录。但是,我希望用户保留在页面上,因此我再次调用View,但尝试获取更新的模型,以便我拥有任何新创建的RolePermission对象的ID。我没有将新ID添加到HiddenFor字段中。

这是我的班级:

RolePermissionVM

我的控制器代码:

public class RolePermissionVM
{
    public int? RolePermissionId { get; set; }
    public int RoleId { get; set; }
    public int PermissionId { get; set; }
    public string PermissionName { get; set; }

    public bool IsActive { get; set; }
}

CheckBox列表的每一行使用的局部视图:

    private RoleVM GetRoleVm(int id)
    {
        var thisRoleVm = (from r in db.Role
            where r.RoleId == id
            select new RoleVM
            {
                RoleId = r.RoleId,
                RoleName = r.RoleName,
                RoleDescription = r.RoleDescription,
                OwnerId = r.OwnerId,
                IsActive = r.IsActive
            }).FirstOrDefault();
        thisRoleVm.RolePermission = (from p in db.Permission
                                     join rPerm in
                                         (from rp in db.RolePermission
                                          where rp.RoleId == id
                                          select rp)
                                         on p.PermissionId equals rPerm.PermissionId into pp
                                     from rps in pp.DefaultIfEmpty()
                                     select new RolePermissionVM
                                     {
                                         RolePermissionId = (int?)rps.RolePermissionId,
                                         RoleId = id,
                                         PermissionId = p.PermissionId,
                                         PermissionName = p.PermissionName,
                                         IsActive = (rps.IsActive == null ? false : rps.IsActive)
                                     })
                                     .OrderBy(p => p.PermissionName).ToList();
        return thisRoleVm;
    }

    [HttpPost, ActionName("_roleedit")]
    [ValidateAntiForgeryToken]
    public ActionResult _RoleEdit(RoleVM editedRole)
    {
        //...

        if (ModelState.IsValid)
        {
            var dbRole = db.Role.Find(editedRole.RoleId);
            dbRole.RoleName = editedRole.RoleName;
            dbRole.RoleDescription = editedRole.RoleDescription;
            dbRole.OwnerId = editedRole.OwnerId;

            foreach (var thisPerm in editedRole.RolePermission) // RolePermission here is the ViewModel, not the actual model
            {
                if (thisPerm.RolePermissionId != null && thisPerm.RolePermissionId > 0)
                {
                    // We have a record for this, let's just update it
                    var thisRolePerm =
                        dbRole.RolePermission.FirstOrDefault(rp => rp.RolePermissionId == thisPerm.RolePermissionId);
                    thisRolePerm.IsActive = thisPerm.IsActive;
                    db.Entry(thisRolePerm).State = EntityState.Modified;
                }
                else
                {
                    if (thisPerm.IsActive)
                    {
                        // New and active, so we add it
                        dbRole.RolePermission.Add(new RolePermission
                        {
                            RoleId = editedRole.RoleId,
                            PermissionId = thisPerm.PermissionId,
                            IsActive = true
                        });
                    }
                }
            }

            db.Entry(dbRole).State = EntityState.Modified;
            db.SaveChanges(User.ProfileId);

            var newEditedRole = GetRoleVm(editedRole.RoleId); // We don't get the new IDs here, but I would like to
            newEditedRole.ResponseMessage = "Saved Successfully";

            return View(newEditedRole); // This should have the new RolePermissionId values, but it doesn't.
        }
    editedRole.ResponseMessage = "Error Saving";
        return View(editedRole);
    }

@using PublicationSystem.Tools @model PublicationSystem.Areas.Admin.Models.RolePermissionVM <li class="editorRow ui-state-default removable-row"> @using (Html.BeginCollectionItem("RolePermission")) { <div class="row"> @Html.HiddenFor(model => model.RolePermissionId) @Html.HiddenFor(model => model.RoleId) @Html.HiddenFor(model => model.PermissionId) @Html.HiddenFor(model => model.PermissionName) <div class="col-md-7"> @Html.DisplayFor(model => model.PermissionName, new {htmlAttributes = new {@class = "form-control"}}) </div> <div class="col-md-3"> @Html.CheckBoxFor(model => model.IsActive, new { htmlAttributes = new { @class = "form-control" } }) </div> </div> } </li> 应该调用数据库来获取更新的ID,但事实并非如此。我认为问题是DBContext使用的是缓存副本。

那么,为什么新数据库生成的ID不会被撤回?我该如何解决这个问题?有没有更有效的方法来做到这一点?

1 个答案:

答案 0 :(得分:0)

您必须致电return RedirectToAction("ViewName")而不是return View(newEditedRole);

另一种方法是从ModelState中删除值,因此它将在视图上更新:

ModelState.Remove("RoleId")
model.RoleId = dbRole.RoleId

我认为return RedirectToAction("ViewName")是更好/更可靠的选择。