public async Task ShouldGetEntityInDbTransactionAsync() { var originalEntity = this.CreateEntity(); using (var dbContextScope = this.dbContextScopeFactory.CreateWithTransaction(IsolationLevel.ReadUncommitted)) { var dbContext = dbContextScope.DbContexts.Get <ApplicationDbContext>(); dbContext.ToDoItems.Add(originalEntity); await dbContextScope.SaveChangesAsync(); Assert.IsTrue(originalEntity.Id != 0); } // An example of explicit database transaction. // Read the comment for CreateReadOnlyWithTransaction() before using this overload as there are gotchas when doing this! using (var dbContextScope = new DbContextReadOnlyScope(IsolationLevel.ReadUncommitted)) { var dbContext = dbContextScope.DbContexts.Get <ApplicationDbContext>(); var actualEntity = await dbContext.ToDoItems.AsQueryable().FirstOrDefaultAsync(e => e.Id == originalEntity.Id); Assert.IsNotNull(actualEntity); Assert.AreEqual(originalEntity, actualEntity); } }
public async Task ShouldGetEntitiesAsync() { /* A very contrived example of ambient DbContextScope within an async flow. * * Note that the ConfigureAwait(false) calls here aren't strictly necessary * and are unrelated to DbContextScope. You can remove them if you want and * the code will run in the same way. It is however good practice to configure * all your awaitables in library code to not continue * on the captured synchronization context. It avoids having to pay the overhead * of capturing the sync context and running the task continuation on it when * library code doesn't need that context. If also helps prevent potential deadlocks * if the upstream code has been poorly written and blocks on async tasks. * * "Library code" is any code in layers under the presentation tier. Typically any code * other that code in ASP.NET MVC / WebApi controllers or Window Form / WPF forms. * * See http://blogs.msdn.com/b/pfxteam/archive/2012/04/13/10293638.aspx for * more details. */ var originalEntities = this.CreateEntities(NumberOfEntitiesToCreate); using (var dbContextParentScope = this.dbContextScopeFactory.Create()) { foreach (var entity in originalEntities) { using (var dbContextNestedScope = this.dbContextScopeFactory.Create()) { var dbContext = dbContextNestedScope.DbContexts.Get <ApplicationDbContext>(); dbContext.ToDoItems.Add(entity); dbContextNestedScope.SaveChanges(); Assert.IsTrue(entity.Id == 0); } } dbContextParentScope.SaveChanges(); foreach (var entity in originalEntities) { Assert.IsTrue(entity.Id != 0); } } var entityIds = originalEntities.Select(e => e.Id).ToList(); var actualEntities = new List <ToDoItem>(); using (var dbContextScope = new DbContextReadOnlyScope()) { var dbContext = dbContextScope.DbContexts.Get <ApplicationDbContext>(); foreach (var entityId in entityIds) { var entity = await dbContext.ToDoItems.FirstOrDefaultAsync(e => e.Id == entityId).ConfigureAwait(false); // We're now in the continuation of the first async task. This is most // likely executing in a thread from the ThreadPool, i.e. in a different // thread that the one where we created our DbContextScope. Our ambient // DbContextScope is still available here however, which allows the call // below to succeed. actualEntities.Add(entity); } } Assert.AreEqual(originalEntities.Count, actualEntities.Count()); }