public virtual async Task SaveChanges_uses_ambient_transaction(bool async, bool autoTransactionsEnabled)
        {
            if (!AmbientTransactionsSupported)
            {
                return;
            }

            if (TestStore.ConnectionState == ConnectionState.Closed)
            {
                TestStore.OpenConnection();
            }

            using (TestUtilities.TestStore.CreateTransactionScope())
            {
                using (var context = CreateContext())
                {
                    context.Database.AutoTransactionsEnabled = autoTransactionsEnabled;

                    context.Add(
                        new TransactionCustomer
                    {
                        Id   = 77,
                        Name = "Bobble"
                    });

                    // Issue #14935. Cannot eval 'Last()'
                    // Use AsEnumerable().
                    context.Entry(context.Set <TransactionCustomer>().AsEnumerable().Last()).State = EntityState.Added;

                    if (async)
                    {
                        await Assert.ThrowsAsync <DbUpdateException>(() => context.SaveChangesAsync());
                    }
                    else
                    {
                        Assert.Throws <DbUpdateException>(() => context.SaveChanges());
                    }

                    context.Database.AutoTransactionsEnabled = true;
                }

                Assert.Equal(
                    RelationalResources.LogAmbientTransactionEnlisted(new TestLogger <TestRelationalLoggingDefinitions>()).GenerateMessage("Serializable"),
                    Fixture.ListLoggerFactory.Log.First().Message);
            }

            AssertStoreInitialState();
        }
예제 #2
0
 public virtual void UseTransaction_throws_if_another_transaction_started()
 {
     using (var transaction = TestStore.BeginTransaction())
     {
         using (var context = CreateContextWithConnectionString())
         {
             using (context.Database.BeginTransaction())
             {
                 var ex = Assert.Throws <InvalidOperationException>(
                     () =>
                     context.Database.UseTransaction(transaction));
                 Assert.Equal(RelationalStrings.TransactionAlreadyStarted, ex.Message);
             }
         }
     }
 }
예제 #3
0
        public virtual void UseTransaction_throws_if_ambient_transaction_started()
        {
            if (!AmbientTransactionsSupported)
            {
                return;
            }

            using (TestUtilities.TestStore.CreateTransactionScope())
            {
                using var transaction = TestStore.BeginTransaction();
                using var context     = CreateContextWithConnectionString();
                var ex = Assert.Throws <InvalidOperationException>(
                    () => context.Database.UseTransaction(transaction));
                Assert.Equal(RelationalStrings.ConflictingAmbientTransaction, ex.Message);
            }
        }
예제 #4
0
        public virtual void SaveChanges_allows_independent_ambient_transaction_commits()
        {
            if (!AmbientTransactionsSupported)
            {
                return;
            }

            if (TestStore.ConnectionState == ConnectionState.Closed)
            {
                TestStore.OpenConnection();
            }

            using (var context = CreateContext())
            {
                using (var tr = new TransactionScope())
                {
                    context.Add(new TransactionCustomer {
                        Id = 77, Name = "Bobble"
                    });
                    context.SaveChanges();
                    TestStore.CloseConnection();
                    using (var nestedTransaction = new TransactionScope(TransactionScopeOption.RequiresNew))
                    {
                        context.Add(new TransactionOrder {
                            Id = 300, Name = "Order3"
                        });
                        context.SaveChanges();
                        nestedTransaction.Complete();
                        TestStore.CloseConnection();
                    }
                }

                Assert.Equal(
                    new List <int> {
                    1, 2
                },
                    context.Set <TransactionCustomer>().OrderBy(c => c.Id).Select(e => e.Id).ToList());
                Assert.Equal(
                    new List <int>
                {
                    100,
                    200,
                    300
                },
                    context.Set <TransactionOrder>().OrderBy(c => c.Id).Select(e => e.Id).ToList());
            }
        }
        public virtual async Task SaveChanges_uses_enlisted_transaction_after_connection_closed(bool async, bool autoTransactionsEnabled)
        {
            if (!AmbientTransactionsSupported)
            {
                return;
            }

            using (var context = CreateContext())
            {
                using (var transaction = new CommittableTransaction(TimeSpan.FromMinutes(10)))
                {
                    context.Database.EnlistTransaction(transaction);
                    context.Database.AutoTransactionsEnabled = autoTransactionsEnabled;

                    context.Add(
                        new TransactionCustomer
                    {
                        Id   = 77,
                        Name = "Bobble"
                    });

                    // Issue #14935. Cannot eval 'Last()'
                    // Use AsEnumerable().
                    context.Entry(context.Set <TransactionCustomer>().AsEnumerable().Last()).State = EntityState.Added;

                    context.Database.AutoTransactionsEnabled = true;
                }

                using (var transaction = new CommittableTransaction(TimeSpan.FromMinutes(10)))
                {
                    TestStore.CloseConnection();
                    TestStore.OpenConnection();
                    context.Database.EnlistTransaction(transaction);

                    if (async)
                    {
                        await Assert.ThrowsAsync <DbUpdateException>(() => context.SaveChangesAsync());
                    }
                    else
                    {
                        Assert.Throws <DbUpdateException>(() => context.SaveChanges());
                    }
                }
            }

            AssertStoreInitialState();
        }
예제 #6
0
        public virtual async Task Can_use_open_connection_with_started_transaction(bool autoTransaction)
        {
            using (var transaction = TestStore.BeginTransaction())
            {
                using (var context = CreateContext())
                {
                    context.Database.AutoTransactionsEnabled = autoTransaction;

                    context.Database.UseTransaction(transaction);

                    context.Entry(context.Set <TransactionCustomer>().OrderBy(c => c.Id).First()).State = EntityState.Deleted;
                    await context.SaveChangesAsync();
                }
            }

            AssertStoreInitialState();
        }
        protected TestStore CreateTestStore(Action <ModelBuilder> onModelCreating)
        {
            TestStore = TestStoreFactory.Create(DatabaseName);

            ServiceProvider = TestStoreFactory.AddProviderServices(new ServiceCollection())
                              .AddSingleton(TestModelSource.GetFactory(onModelCreating))
                              .BuildServiceProvider(validateScopes: true);

            TestStore.Initialize(ServiceProvider, CreateContext, c => ((TransportationContext)c).Seed());

            TestSqlLoggerFactory.Clear();

            // To enable logging
            //TestSqlLoggerFactory.SetTestOutputHelper(TestOutputHelper);

            return(TestStore);
        }
예제 #8
0
        public virtual async Task Seeding_does_not_leave_context_contaminated(bool async)
        {
            using var context = CreateContextWithEmptyDatabase(async ? "1A" : "1S");
            TestStore.Clean(context);
            var _ = async
                ? await context.Database.EnsureCreatedResilientlyAsync()
                : context.Database.EnsureCreatedResiliently();

            Assert.Empty(context.ChangeTracker.Entries());

            var seeds = context.Set <Seed>().OrderBy(e => e.Id).ToList();

            Assert.Equal(2, seeds.Count);
            Assert.Equal(321, seeds[0].Id);
            Assert.Equal("Apple", seeds[0].Species);
            Assert.Equal(322, seeds[1].Id);
            Assert.Equal("Orange", seeds[1].Species);
        }
        public override CrossStoreContext CreateContext(TestStore testStore)
        {
            var inMemoryTestStore = testStore as InMemoryTestStore;

            if (inMemoryTestStore != null)
            {
                var optionsBuilder = new DbContextOptionsBuilder()
                                     .UseInMemoryDatabase(StoreName)
                                     .UseInternalServiceProvider(_serviceProvider);

                return(new CrossStoreContext(optionsBuilder.Options));
            }

            var sqliteTestStore = testStore as SqliteTestStore;

            if (sqliteTestStore != null)
            {
                var optionsBuilder = new DbContextOptionsBuilder();
                optionsBuilder.UseSqlite(sqliteTestStore.Connection);

                var context = new CrossStoreContext(optionsBuilder.Options);
                context.Database.EnsureCreated();
                context.Database.UseTransaction(sqliteTestStore.Transaction);

                return(context);
            }

            /* CHANGED: No SQL Server on Xamarin.iOS
             * var sqlServerTestStore = testStore as SqlServerTestStore;
             * if (sqlServerTestStore != null)
             * {
             *  var optionsBuilder = new DbContextOptionsBuilder();
             *  optionsBuilder.UseSqlServer(sqlServerTestStore.Connection, b => b.ApplyConfiguration());
             *
             *  var context = new CrossStoreContext(optionsBuilder.Options);
             *  context.Database.EnsureCreated();
             *  context.Database.UseTransaction(sqlServerTestStore.Transaction);
             *
             *  return context;
             * } */

            throw new NotImplementedException();
        }
예제 #10
0
 public virtual void UseTransaction_throws_if_another_transaction_started()
 {
     using (var transaction = TestStore.BeginTransaction())
     {
         using (var context = CreateContextWithConnectionString())
         {
             using (context.Database.BeginTransaction(
                        DirtyReadsOccur
                     ? System.Data.IsolationLevel.ReadUncommitted
                     : System.Data.IsolationLevel.Unspecified))
             {
                 var ex = Assert.Throws <InvalidOperationException>(
                     () =>
                     context.Database.UseTransaction(transaction));
                 Assert.Equal(RelationalStrings.TransactionAlreadyStarted, ex.Message);
             }
         }
     }
 }
예제 #11
0
        public virtual void UseTransaction_throws_if_enlisted_in_transaction()
        {
            if (!AmbientTransactionsSupported)
            {
                return;
            }

            using var t           = new CommittableTransaction(TimeSpan.FromMinutes(10));
            using var transaction = TestStore.BeginTransaction();
            using var context     = CreateContextWithConnectionString();
            context.Database.OpenConnection();

            context.Database.EnlistTransaction(t);

            var ex = Assert.Throws <InvalidOperationException>(
                () => context.Database.UseTransaction(transaction));

            Assert.Equal(RelationalStrings.ConflictingEnlistedTransaction, ex.Message);
            context.Database.CloseConnection();
        }
        protected TestStore CreateTestStore(Action <ModelBuilder> onModelCreating, bool seed = true)
        {
            TestStore = TestStoreFactory.Create(DatabaseName);

            ServiceProvider = TestStoreFactory.AddProviderServices(new ServiceCollection())
                              .AddSingleton(TestModelSource.GetFactory(onModelCreating))
                              .AddSingleton <ILoggerFactory>(TestSqlLoggerFactory)
                              .BuildServiceProvider(validateScopes: true);

            TestStore.Initialize(ServiceProvider, CreateContext, c =>
            {
                if (seed)
                {
                    ((TransportationContext)c).Seed();
                }
            });

            TestSqlLoggerFactory.Clear();

            return(TestStore);
        }
예제 #13
0
        private ContextFactory <TContext> Initialize <TContext>(
            Action <ModelBuilder> onModelCreating,
            Action <DbContextOptionsBuilder> onConfiguring,
            Action <IServiceCollection> addServices,
            Func <string, bool> shouldLogCategory,
            Func <TestStore> createTestStore,
            bool usePooling)
            where TContext : DbContext
        {
            _testStore = createTestStore?.Invoke() ?? CreateTestStore();

            shouldLogCategory ??= _ => false;
            var services = TestStoreFactory.AddProviderServices(new ServiceCollection())
                           .AddSingleton <ILoggerFactory>(TestStoreFactory.CreateListLoggerFactory(shouldLogCategory));

            if (onModelCreating != null)
            {
                services = services.AddSingleton(TestModelSource.GetFactory(onModelCreating));
            }

            if (addServices != null)
            {
                addServices(services);
            }

            services = usePooling
                ? services.AddDbContextPool(typeof(TContext), (s, b) => ConfigureOptions(s, b, onConfiguring))
                : services.AddDbContext(
                typeof(TContext),
                (s, b) => ConfigureOptions(s, b, onConfiguring),
                ServiceLifetime.Transient,
                ServiceLifetime.Singleton);

            _serviceProvider = services.BuildServiceProvider(validateScopes: true);

            var contextFactory = new ContextFactory <TContext>(_serviceProvider, usePooling, _testStore);

            return(contextFactory);
        }
        public virtual void SaveChanges_uses_enlisted_transaction_after_ambient_transaction()
        {
            if (!AmbientTransactionsSupported)
            {
                return;
            }

            if (TestStore.ConnectionState == ConnectionState.Closed)
            {
                TestStore.OpenConnection();
            }

            using (var context = CreateContext())
            {
                using (TestUtilities.TestStore.CreateTransactionScope())
                {
                    context.Add(
                        new TransactionCustomer
                    {
                        Id   = 77,
                        Name = "Bobble"
                    });

                    // Issue #14935. Cannot eval 'Last()'
                    // Use AsEnumerable().
                    context.Entry(context.Set <TransactionCustomer>().AsEnumerable().Last()).State = EntityState.Added;
                }

                using (var transaction = new CommittableTransaction(TimeSpan.FromMinutes(10)))
                {
                    context.Database.EnlistTransaction(transaction);

                    Assert.Throws <DbUpdateException>(() => context.SaveChanges());
                }
            }

            AssertStoreInitialState();
        }
        protected SharedStoreFixtureBase()
        {
            TestStore = TestStoreFactory.GetOrCreate(StoreName);

            var services = AddServices(TestStoreFactory.AddProviderServices(new ServiceCollection()));

            if (UsePooling)
            {
                services = services.AddDbContextPool(ContextType, (s, b) => ConfigureOptions(s, b));
            }
            else
            {
                services = services.AddDbContext(
                    ContextType,
                    (s, b) => ConfigureOptions(s, b),
                    ServiceLifetime.Transient,
                    ServiceLifetime.Singleton);
            }

            ServiceProvider = services.BuildServiceProvider(validateScopes: true);

            TestStore.Initialize(ServiceProvider, CreateContext, c => Seed((TContext)c), c => Clean(c));
        }
예제 #16
0
 public DbContextOptions CreateOptions(TestStore testStore)
 => AddOptions(testStore.AddProviderOptions(new DbContextOptionsBuilder()))
 .EnableDetailedErrors()
 .UseInternalServiceProvider(ServiceProvider)
 .EnableServiceProviderCaching(false)
 .Options;
예제 #17
0
 public CrossStoreContext CreateContext(TestStore testStore)
 => new CrossStoreContext(CreateOptions(testStore));
예제 #18
0
 public DbContextOptions CreateOptions(TestStore testStore)
 => AddOptions(testStore.AddProviderOptions(new DbContextOptionsBuilder()))
 .UseInternalServiceProvider(testStore.ServiceProvider)
 .Options;
 public DbContextOptions CreateOptions(TestStore testStore)
 => AddOptions(testStore.AddProviderOptions(new DbContextOptionsBuilder()))
 .EnableRichDataErrorHandling()
 .UseInternalServiceProvider(ServiceProvider)
 .Options;
예제 #20
0
 public void Dispose() => TestStore.Dispose();
예제 #21
0
 public override CrossStoreContext CreateContext(TestStore testStore) => _sharedCrossStoreFixture.CreateContext(testStore);
예제 #22
0
 public abstract CrossStoreContext CreateContext(TestStore testStore);
예제 #23
0
 public IEnumerable <T> Query <T>(string sql, params object[] parameters) => TestStore.Query <T>(sql, parameters);
 public EmptyMigrationsContext CreateEmptyContext()
 => new EmptyMigrationsContext(TestStore.AddProviderOptions(new DbContextOptionsBuilder()).Options);