我在我的MVC项目中使用AspNet.Identity
进行用户管理,因为我认为这是一个很好的开始,现在我可以正常工作(几乎没有更改),我想添加一个审计跟踪(跟踪更改)就像我使用的其他DbContext一样。
在IdentityModel.cs
中,我有以下代码有效,但仅在某些情况下有效:
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext()
: base("DefaultConnection", throwIfV1Schema: false)
{
//Can't recall if this was there by default
Configuration.AutoDetectChangesEnabled = true;
}
public override int SaveChanges()
{
//Tell EF to Track Changes
ChangeTracker.DetectChanges();
//More code once I get this working
//
}
}
在我的控制器中,我有以下内容:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Edit(EditUserViewModel editUser)
{
var user = await UserManager.FindByIdAsync(editUser.Id);
//Update a property within the User object
user.FirstName = "Updated First Name";
//Save to database
var result = UserManager.Update(user);
//The above saves to database, but doesn't trigger SaveChanges()
//SaveChanges() will be triggered if I call
HttpContext.GetOwinContext().Get<ApplicationDbContext>().SaveChanges();
}
调用上面的HttpContext.GetOwinContext().Get<ApplicationDbContext>().SaveChanges();
时,更新的ApplicationUser的EntityState
为Unchanged
。有道理,因为它已经保存。
但是,我试图了解如何利用UserManager
并仍然可以与SaveChanges()
一起使用。
我也了解我可以编写一个自己记录所有此类的类,但是当我扩展ApplicationUser(或ApplicationRole)时,我想避免对审计日志进行额外的编码。
任何建议或链接都会有所帮助!
答案 0 :(得分:1)
在UserStore的构造函数中将AutoSaveChanges设置为false(您将传递给UserManager的构造函数)。
public class MyUserStore : UserStore<User, Role, int, UserLogin, UserRole, UserClaim>
{
private MyDbContext _context;
public MyUserStore(MyDbContext context) : base(context)
{
//Set this to false
AutoSaveChanges = false;
_context = context;
}
}
现在,您可以像往常一样调用保存更改,更改跟踪器将包含您期望的更改。
但是,当我尝试在对SaveChanges的调用之间多次对UserManager进行调用时,确实遇到了OptimisticConcurrencyException。我只是在每次UserManager操作之后调用SaveChanges。