使用实体框架更新UserProfile及其角色 [英] Updating a UserProfile and its Roles using Entity Framework

查看:91
本文介绍了使用实体框架更新UserProfile及其角色的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图找到一种方式,允许我更新一个UserProfile实体以及用户分配给的角色列表。我写了下面的代码,但它不起作用。

I'm trying to find a way that would allow me to update a UserProfile entity along with a list of Roles that the user is assigned to. I've written the code below, but it doesn't work.

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

Here is the 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 Edit方法

... and here is the HttpPost Edit method

[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);
    }

有没有人知道为什么这不工作?或者可以在某个实际工作的地方建议一个教程。任何帮助,一如往常,非常感谢。

Does anyone have any idea why this isn't working? Or could suggest a tutorial somewhere that actually works. Any help, as always, is greatly appreciated.

推荐答案

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

Finally found that I had it totally wrong in the first place. I wasn't changing the relationships at all. I've included the code below, which allows me to attach the parent entity as modified and then mark the relationships as added and deleted as required

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);
  }
}

这篇关于使用实体框架更新UserProfile及其角色的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆