UserManager如何与DbContext链接?

时间:2018-03-17 21:49:27

标签: asp.net-mvc asp.net-mvc-5 asp.net-identity dbcontext

我有以下代码:

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
    public ApplicationDbContext()
        : base("AssetContext", throwIfV1Schema: false)
    {
    }

    public static ApplicationDbContext Create()
    {
        return new ApplicationDbContext();
    }
}


public class ApplicationUserManager : UserManager<ApplicationUser>
{
    public ApplicationUserManager(IUserStore<ApplicationUser> store)
        : base(store)
    {
    }

    public static ApplicationUserManager Create(
              IdentityFactoryOptions<ApplicationUserManager> options,
              IOwinContext context)
    {
        ApplicationDbContext dbContext = context.Get<ApplicationDbContext>();
        return Create(options, dbContext);
    }
    .....
}

    private ApplicationUserManager _userManager;
    public ApplicationUserManager UserManager
    {
        get
        {
            return _userManager ?? HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
        }
        private set
        {
            _userManager = value;
        }
    }

然后我有控制器方法:

    public async Task<ActionResult> EditUser(UserEditViewModel model)
    {
                var user = mapper.Map<UserEditViewModel, AspNetUser>(model, _db.AspNetUsers.Where(p => p.UserName == model.UserName).FirstOrDefault());

                    user.CompanyId = null;
                    user.LockoutEnabled = false;
                    user.LockoutEndDateUtc = null;


                _db.SaveChanges();

                    var roles = UserManager.GetRoles(user.Id);
                    UserManager.AddToRole(user.Id, model.RoleName);
                    UserManager.RemoveFromRoles(user.Id, roles.ToArray());

                return RedirectToAction("UserList");
    }

(请不要说我关于DI,我不是代码的所有者:))

问题是用户的所有更改:

                    user.CompanyId = null;
                    user.LockoutEnabled = false;
                    user.LockoutEndDateUtc = null;
当我打电话

时,

被重写

UserManager.AddToRole(user.Id, model.RoleName);

为什么会这样?

1 个答案:

答案 0 :(得分:0)

UserManager直接取决于UserStore,直接取决于IdentityDbContextUserManager中涉及访问db的每个操作都将使用DbContext。特别是UserManager中的写操作将调用dbContext.SaveChangesAsync()

如果您使用了相同的DbContext实例,您将在每次与身份相关的写入时调用SaveChangesAsync(),并且将提交与此上下文相关的所有其他未经修改的更改。

所以你所描述的是拥有相同的DbContext实例并调用保存更改的结果(尽管在Identity框架内部)。

UPD 我想我误解了你的问题。好像你有2个DbContext实例发挥了一场拔河比赛。您有自己的实例和另一个属于Identity的实例。当您致电_db.SaveChanges()时,您将保存上下文中的更改并将其刷新到数据库。与此同时,您有另一个DbContext实例,它不知道您已经完成的任何修改。它跟踪该用户的实例(在其他地方)并保留有关该用户的内部信息,但它不会查询DB中相关记录的更新状态。当您调用UserManager.AddToRole时,状态会再次刷新回DB,但是使用旧值。

所以你的问题确实有2个DbContexts。