ASP.NET MVC5 / EF6 - AutoSaveChanges过早地提交工作单元

时间:2015-05-11 11:17:36

标签: asp.net-mvc entity-framework transactions asp.net-identity transactionscope

所以我发现这是关于过早提交(source):

  

需要注意的一个问题是UserStore类不能播放   当使用工作单元设计模式时。具体来说,   默认情况下,UserStore几乎在每个方法调用中调用SaveChanges,   这使得过早提交工作单元变得容易。改变   此行为,更改UserStore上的AutoSaveChanges标志。

所以问题是更改该标志会使Identity对象更难处理。例如,在创建新用户时,您无法取回其ID。

另外,我如何在像AccountController这样的类中保存更改,默认情况下,您甚至没有(或经常需要)声明ApplicationDbContext而您只有UserManager和SignInManager?我需要实例化一个新的ApplicationDbContext并保存它,这不是一个非常好的解决方案。

我找到了一个使用数据库事务的解决方案,如下所示:

var dbContext = // get instance of your ApplicationDbContext
var userManager = // get instance of your ApplicationUserManager
using (var transaction = dbContext.Database.BeginTransaction(IsolationLevel.ReadCommitted))
{
    try
    {
        var user = // crate your ApplicationUser
        var userCreateResult = await userManger.CreateAsync(user, password);
        if(!userCreateResult.Succeeded)
        {
            // list of errors in userCreateResult.Errors
            transaction.Rollback();
            return userCreateResult.Errors;
        }
        // new Guid for user now saved to user.Id property
        var userId = user.Id;

        var addToRoleresult = await userManager.AddToRoleAsync(user.Id, "My Role Name");
        if(!addToRoleresult.Succeeded)
        {
            // deal with errors
            transaction.Rollback();
            return addToRoleresult.Errors;
        }

        // if we got here, everything worked fine, commit transaction
        transaction.Commit();
    }
    catch (Exception exception)
    {
        transaction.Rollback();
        // log your exception
        throw;
    }
}

(来源:https://stackoverflow.com/a/27367675/3194577

但我对这是如何解决这个问题感到困惑。假设您有这样的执行顺序:

  1. 在上下文中添加/更新内容,但不要将任何内容保存到数据库
  2. 执行UserManager.CreateAsync,这将保存上下文(我们还不想要)
  3. 如果我用交易包围这个,它仍然会以同样的方式发生,除非我可以回滚它,如果我想,对吧?但这并没有真正帮助,只有在出现问题时才会有所帮助,而且我从来没有想过任何错误,这就是为什么我要控制它何时保存。也许我对交易的运作方式感到困惑。

0 个答案:

没有答案