我有以下代码:
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);
为什么会这样?
答案 0 :(得分:0)
UserManager
直接取决于UserStore
,直接取决于IdentityDbContext
。 UserManager
中涉及访问db的每个操作都将使用DbContext。特别是UserManager
中的写操作将调用dbContext.SaveChangesAsync()
。
如果您使用了相同的DbContext实例,您将在每次与身份相关的写入时调用SaveChangesAsync()
,并且将提交与此上下文相关的所有其他未经修改的更改。
所以你所描述的是拥有相同的DbContext实例并调用保存更改的结果(尽管在Identity框架内部)。
UPD 我想我误解了你的问题。好像你有2个DbContext实例发挥了一场拔河比赛。您有自己的实例和另一个属于Identity的实例。当您致电_db.SaveChanges()
时,您将保存上下文中的更改并将其刷新到数据库。与此同时,您有另一个DbContext实例,它不知道您已经完成的任何修改。它跟踪该用户的实例(在其他地方)并保留有关该用户的内部信息,但它不会查询DB中相关记录的更新状态。当您调用UserManager.AddToRole
时,状态会再次刷新回DB,但是使用旧值。
所以你的问题确实有2个DbContexts。