title: ASP.NET MVC5/EF6 - AutoSaveChanges prematurely commiting Unit of Work
body: <p>So I found this about prematurely commiting (<a href="http://odetocode.com/blogs/scott/archive/2014/01/03/asp-net-identity-with-the-entity-framework.aspx" rel="nofollow noreferrer">source</a>):</p>
  
  <blockquote>
    <p>One issue to be aware of is that the UserStore class does not play
    well when using the unit of work design pattern. Specifically, the
    UserStore invokes SaveChanges in nearly every method call by default,
    which makes it easy to prematurely commit a unit of work. To change
    this behavior, change the AutoSaveChanges flag on the UserStore.</p>
  </blockquote>
  
  <p>So the problem is that changing that flag makes working with the Identity objects harder. For example, when creating a new user you don't get back its ID.</p>
  
  <p>Also how would I save the changes in a class like AccountController in which by default you don't even have (or often need) to declare an ApplicationDbContext and you only have a UserManager and a SignInManager? I'd need to instantiate a new ApplicationDbContext and save that, which isn't a very good solution.</p>
  
  <p>I found a solution that consisted of using database transactions, so something like this:</p>
  
  <pre class="lang-cs prettyprint-override"><code>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;
      }
  }
  </code></pre>
  
  <p>(source: <a href="https://stackoverflow.com/a/27367675/3194577">https://stackoverflow.com/a/27367675/3194577</a>)</p>
  
  <p>But I'm confused about how this really fixes anything. Lets say you have an execution order like this:</p>
  
  <ol>
  <li>Add/Update something in the context, but don't save anything to the database</li>
  <li>Execute UserManager.CreateAsync which would save the context (which we don't want yet)</li>
  </ol>
  
  <p>If I surround this with a transaction, it would still happen the same way, except I could rollback it if I'd want to, right? But that doesn't really help, it only helps if something does go wrong, and I never want anything to wrong in the first place which is why I want control over when it saves. Maybe I'm just confused about how transactions work.</p>