0

我正在尝试找到一种方法,允许我更新 UserProfile 实体以及分配给用户的角色列表。我已经编写了下面的代码,但它不起作用。

public void UpdateUserProfile(UserProfile userProfile)
{
  context.Entry(userProfile).State = EntityState.Added;

  var databaseRoleIds = context.Roles
    .Where(r => r.UserProfiles
      .Any(u => u.UserId == userProfile.UserId))
      .Select(r => r.RoleId).ToList();

  var clientRoleIds = userProfile.Roles.Select(r => r.RoleId).ToList();

  var removedRoleIds = databaseRoleIds.Except(clientRoleIds).ToList();

  var addedRoleIds = clientRoleIds.Except(databaseRoleIds).ToList();

  var unchangedRoleIds = removedRoleIds.Union(addedRoleIds).ToList();

  foreach (var roleId in unchangedRoleIds)
  {
    var role = context.Roles.Find(roleId);
    context.Entry(role).State = EntityState.Unchanged;
  }

  foreach (var roleId in removedRoleIds)
  {
    userProfile.RemoveRole(context.Roles.Find(roleId));
  }

  foreach (var roleId in addedRoleIds)
  {
    userProfile.AddRole(context.Roles.Find(roleId));
  }

  context.Entry(userProfile).State = EntityState.Modified;

}

这是unitOfWork

namespace MvcWebsite.WorkUnits
{
public class WorkUnit : IWorkUnit, IDisposable
{
private MvcContext context = new MvcContext();
private RoleRepository roleRepository;
private UserProfileRepository userProfileRepository;

public IRoleRepository RoleRepository
{
  get
  {
    if (this.roleRepository == null)
    {
      roleRepository = new RoleRepository(context);
    }
    return roleRepository;
  }
}

public IUserProfileRepository UserProfileRepository
{
  get
  {
    if (this.userProfileRepository == null)
    {
      userProfileRepository = new UserProfileRepository(context);
    }
    return userProfileRepository;
  }
}

public void Save()
{
  context.SaveChanges();
}

private bool disposed = false;

protected virtual void Dispose(bool disposing)
{
  if (!this.disposed)
  {
    if (disposing)
    {
      context.Dispose();
    }
  }
  this.disposed = true;
}

public void Dispose()
{
  Dispose(true);
  GC.SuppressFinalize(this);
}

}
}

...这是 HttpPost 编辑方法

[HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Edit(UserProfileEditViewModel model)
    {
      try
      {
        if (ModelState.IsValid)
        {
          var clientUserProfile = new UserProfile();
          clientUserProfile.UserId = model.UserId;
          clientUserProfile.UserName = model.UserName;
          clientUserProfile.FirstName = model.FirstName;
          clientUserProfile.LastName = model.LastName;
          clientUserProfile.Email = model.Email;
          clientUserProfile.RowVersion = model.RowVersion;
          clientUserProfile.Roles = new List<Role>();
          foreach(var role in model.Roles)
          {
            if (role.Assigned)
            {
              clientUserProfile.Roles.Add(new Role
              {
                RoleId = role.RoleId,
                RoleName = role.RoleName,
                RowVersion = role.RowVersion,
              });
            }

          }
          unitOfWork.UserProfileRepository.UpdateUserProfile(clientUserProfile);
          unitOfWork.Save();
          return RedirectToAction("Details", new { id = clientUserProfile.UserId });

        }
      }
      catch (DataException ex)
      {
        ModelState.AddModelError("", "Unable to save changes.  Try again, and if the problem persists, see your system administrator.");
      }
      return View(model);
    }

有谁知道为什么这不起作用?或者可以在某个地方推荐一个实际有效的教程。任何帮助,一如既往,非常感谢。

4

2 回答 2

0

UserProfile不要在控制器中创建新的,而是UserProfile从存储库中获取,修改其字段,然后将其发送回UpdateUserProfile并调用Save.

于 2013-06-06T12:56:51.023 回答
0

最后发现我一开始就完全错了。我根本没有改变关系。我已经包含了下面的代码,它允许我将父实体附加为已修改,然后根据需要将关系标记为添加和删除

public void UpdateUserProfile(UserProfile userProfile)
{
  context.Entry(userProfile).State = EntityState.Modified;
  var objectContext = ((IObjectContextAdapter)context).ObjectContext;

  foreach (var role in userProfile.Roles)
  {
    context.Entry(role).State = EntityState.Unchanged;
  }

  var databaseRoleIds = context.Roles
    .Where(r => r.UserProfiles
      .Any(u => u.UserId == userProfile.UserId))
      .Select(r => r.RoleId)
      .ToList();

  var clientRoleIds = userProfile.Roles.Select(r => r.RoleId).ToList();

  var removedRoleIds = databaseRoleIds.Except(clientRoleIds).ToList();

  var addedRoleIds = clientRoleIds.Except(databaseRoleIds).ToList();

  foreach (var roleId in removedRoleIds)
  {
    var role = context.Roles.Find(roleId);
    objectContext
      .ObjectStateManager
      .ChangeRelationshipState(userProfile, role, u => u.Roles, EntityState.Deleted);
  }

  foreach (var roleId in addedRoleIds)
  {
    var role = context.Roles.Find(roleId);
    objectContext
      .ObjectStateManager
      .ChangeRelationshipState(userProfile, role, u => u.Roles, EntityState.Added);
  }
}
于 2013-06-06T18:24:13.340 回答