示例#1
0
        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);
            }
        }
示例#2
0
        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());
        }