예제 #1
0
        public void Should_create_new_child_transaction_and_commit_correctly()
        {
            using (var tx = SUT.BeginTransaction())
                using (var child = SUT.BeginTransaction())
                {
                    ActDbContext.TestEntities.Add(new TestEntity());
                    ActDbContext.SaveChanges();

                    child.Commit();
                    tx.Commit();
                }

            AssertDbContext.TestEntities.Should().HaveCount(1);
        }
예제 #2
0
        public void Should_do_nothing_when_disposing_multiple_times()
        {
            var rootTx = SUT.BeginTransaction();

            ActDbContext.Add(new TestEntity());
            ActDbContext.SaveChanges();

            rootTx.Dispose();
            rootTx.Dispose();

            SUT.CurrentTransaction.Should().BeNull();
            IsTransactionUsable(rootTx.GetDbTransaction()).Should().BeFalse();
            AssertDbContext.TestEntities.Should().HaveCount(0);
        }
예제 #3
0
        public async Task Should_create_pk_by_default_on_string_column()
        {
            ConfigureModel = builder => builder.ConfigureTempTable <string>().Property(t => t.Column1).HasMaxLength(100).IsRequired();

            await using var tempTable = await ActDbContext.BulkInsertValuesIntoTempTableAsync(new List <string> { "value" }, new SqlServerTempTableBulkInsertOptions
            {
                TableNameProvider  = DefaultTempTableNameProvider.Instance,
                PrimaryKeyCreation = PrimaryKeyPropertiesProviders.AdaptiveForced
            });

            var keys = AssertDbContext.GetTempTableKeyColumns <TempTable <string> >().ToList();

            keys.Should().HaveCount(1);
            keys[0].COLUMN_NAME.Should().Be(nameof(TempTable <string> .Column1));
        }
예제 #4
0
        public async Task Should_insert_nullable_int()
        {
            ConfigureModel = builder => builder.ConfigureTempTable <int?>();

            var values = new List <int?> {
                1, null
            };
            var query = await ActDbContext.BulkInsertValuesIntoTempTableAsync(values, new SqlTempTableBulkInsertOptions { PrimaryKeyCreation = PrimaryKeyCreation.None }).ConfigureAwait(false);

            var tempTable = await query.ToListAsync().ConfigureAwait(false);

            tempTable.Should()
            .HaveCount(2).And
            .BeEquivalentTo(new TempTable <int?>(1), new TempTable <int?>(null));
        }
예제 #5
0
        public async Task Should_create_pk_by_default()
        {
            ConfigureModel = builder => builder.ConfigureTempTable <int>();

            await using var tempTable = await ActDbContext.BulkInsertValuesIntoTempTableAsync(new List <int> { 1 }, new SqlServerTempTableBulkInsertOptions
            {
                TableNameProvider  = DefaultTempTableNameProvider.Instance,
                PrimaryKeyCreation = PrimaryKeyPropertiesProviders.AdaptiveForced
            });

            var keys = ArrangeDbContext.GetTempTableKeyColumns <TempTable <int> >().ToList();

            keys.Should().HaveCount(1);
            keys[0].COLUMN_NAME.Should().Be(nameof(TempTable <int> .Column1));
        }
예제 #6
0
        public async Task Should_insert_int()
        {
            ConfigureModel = builder => builder.ConfigureTempTable <int>();

            var values = new List <int> {
                1, 2
            };
            var query = await ActDbContext.BulkInsertValuesIntoTempTableAsync(values).ConfigureAwait(false);

            var tempTable = await query.ToListAsync().ConfigureAwait(false);

            tempTable.Should()
            .HaveCount(2).And
            .BeEquivalentTo(new TempTable <int>(1), new TempTable <int>(2));
        }
예제 #7
0
        public async Task Should_create_pk_if_options_flag_is_set()
        {
            _optionsWithNonUniqueName.PrimaryKeyCreation = PrimaryKeyPropertiesProviders.AdaptiveForced;

            ConfigureModel = builder => builder.ConfigureTempTable <int, string>().Property(s => s.Column2).HasMaxLength(100);

            // ReSharper disable once RedundantArgumentDefaultValue
            await using var tempTable = await SUT.CreateTempTableAsync(ActDbContext.GetEntityType <TempTable <int, string> >(), _optionsWithNonUniqueName);

            var keyColumns = await AssertDbContext.GetTempTableKeyColumns <TempTable <int, string> >().ToListAsync();

            keyColumns.Should().HaveCount(2);
            keyColumns[0].Name.Should().Be(nameof(TempTable <int, string> .Column1));
            keyColumns[1].Name.Should().Be(nameof(TempTable <int, string> .Column2));
        }
        public async Task Should_insert_queryType()
        {
            ConfigureModel = builder => builder.ConfigureTempTableEntity <CustomTempTable>().Property(t => t.Column2).HasMaxLength(100).IsRequired();

            var entities = new List <CustomTempTable> {
                new CustomTempTable(1, "value")
            };
            var query = await ActDbContext.BulkInsertIntoTempTableAsync(entities);

            var tempTable = await query.ToListAsync();

            tempTable.Should()
            .HaveCount(1).And
            .BeEquivalentTo(new CustomTempTable(1, "value"));
        }
예제 #9
0
        public async Task Should_create_temp_table_for_entityType()
        {
            // ReSharper disable once RedundantArgumentDefaultValue
            await using var tempTable = await SUT.CreateTempTableAsync(ActDbContext.GetEntityType <TestEntity>(), _optionsWithNonUniqueName);

            var columns = AssertDbContext.GetTempTableColumns <TestEntity>().OrderBy(c => c.Name).ToList();

            columns.Should().HaveCount(6);

            ValidateColumn(columns[0], nameof(TestEntity.ConvertibleClass), "INTEGER", true);
            ValidateColumn(columns[1], nameof(TestEntity.Count), "INTEGER", false);
            ValidateColumn(columns[2], nameof(TestEntity.Id), "TEXT", false);
            ValidateColumn(columns[3], nameof(TestEntity.Name), "TEXT", true);
            ValidateColumn(columns[4], nameof(TestEntity.PropertyWithBackingField), "INTEGER", false);
            ValidateColumn(columns[5], "_privateField", "INTEGER", false);
        }
예제 #10
0
        public void Should_dispose_inner_child_transactions_if_outer_transactions_is_disposed()
        {
            using (var tx = SUT.BeginTransaction())
            {
                var child      = SUT.BeginTransaction();
                var otherChild = SUT.BeginTransaction();

                ActDbContext.TestEntities.Add(new TestEntity());
                ActDbContext.SaveChanges();

                child.Dispose();
            }

            SUT.CurrentTransaction.Should().BeNull();
            AssertDbContext.TestEntities.Should().HaveCount(0);
        }
예제 #11
0
        public void Should_throw_when_rollback_child_transaction_if_another_child_transaction_is_not_completed()
        {
            // ReSharper disable once UnusedVariable
            var rootTx         = SUT.BeginTransaction();
            var childTx        = SUT.BeginTransaction();
            var anotherChildTx = SUT.BeginTransaction();

            ActDbContext.Add(new TestEntity());
            ActDbContext.SaveChanges();

            childTx.Invoking(tx => tx.Rollback())
            .Should().Throw <InvalidOperationException>().WithMessage("Transactions nested incorrectly. At least one of the child transactions is not completed.");

            SUT.CurrentTransaction.Should().Be(anotherChildTx);
            IsTransactionUsable(anotherChildTx.GetDbTransaction()).Should().BeTrue();
        }
        public async Task Should_create_primary_key_for_entityType()
        {
            var tableName = await ArrangeDbContext.CreateTempTableAsync <TestEntity>();

            await _sut.CreatePrimaryKeyAsync(ActDbContext, ActDbContext.GetEntityType <TestEntity>(), tableName);

            var constraints = await AssertDbContext.GetTempTableConstraints <TestEntity>().ToListAsync();

            constraints.Should().HaveCount(1)
            .And.Subject.First().CONSTRAINT_TYPE.Should().Be("PRIMARY KEY");

            var keyColumns = await AssertDbContext.GetTempTableKeyColumns <TestEntity>().ToListAsync();

            keyColumns.Should().HaveCount(1)
            .And.Subject.First().COLUMN_NAME.Should().Be(nameof(TestEntity.Id));
        }
        public async Task Should_create_temp_table_for_entityType()
        {
            // ReSharper disable once RedundantArgumentDefaultValue
            await _sut.CreateTempTableAsync(ActDbContext, ActDbContext.GetEntityType <TestEntity>(), new TempTableCreationOptions()).ConfigureAwait(false);

            var columns = AssertDbContext.GetCustomTempTableColumns <TestEntity>().OrderBy(c => c.COLUMN_NAME).ToList();

            columns.Should().HaveCount(6);

            ValidateColumn(columns[0], "_privateField", "int", false);
            ValidateColumn(columns[1], nameof(TestEntity.Count), "int", false);
            ValidateColumn(columns[2], nameof(TestEntity.Id), "uniqueidentifier", false);
            ValidateColumn(columns[3], nameof(TestEntity.Name), "nvarchar", true);
            ValidateColumn(columns[4], nameof(TestEntity.PropertyWithBackingField), "int", false);
            ValidateColumn(columns[5], "ShadowProperty", "nvarchar", true);
        }
예제 #14
0
        public async Task Should_insert_nullable_int_of_a_keyless_entity()
        {
            ConfigureModel = builder => builder.ConfigureTempTable <int?>();

            var values = new List <int?> {
                1, null
            };

            await using var query = await ActDbContext.BulkInsertValuesIntoTempTableAsync(values, new SqlServerTempTableBulkInsertOptions { PrimaryKeyCreation = PrimaryKeyPropertiesProviders.None });

            var tempTable = await query.Query.ToListAsync();

            tempTable.Should()
            .HaveCount(2).And
            .BeEquivalentTo(new TempTable <int?>(1), new TempTable <int?>(null));
        }
예제 #15
0
        public async Task Should_insert_string()
        {
            ConfigureModel = builder => builder.ConfigureTempTable <string?>().Property(t => t.Column1).IsRequired(false);

            var values = new List <string?> {
                "value1", null
            };

            await using var query = await ActDbContext.BulkInsertValuesIntoTempTableAsync(values, new SqlServerTempTableBulkInsertOptions { PrimaryKeyCreation = PrimaryKeyPropertiesProviders.None });

            var tempTable = await query.Query.ToListAsync();

            tempTable.Should()
            .HaveCount(2).And
            .BeEquivalentTo(new TempTable <string?>("value1"), new TempTable <string?>(null));
        }
예제 #16
0
        public void Should_commit_children_and_root_transactions()
        {
            var rootTx         = SUT.BeginTransaction();
            var childTx        = SUT.BeginTransaction();
            var anotherChildTx = SUT.BeginTransaction();

            ActDbContext.Add(new TestEntity());
            ActDbContext.SaveChanges();

            anotherChildTx.Commit();
            childTx.Commit();
            rootTx.Commit();

            SUT.CurrentTransaction.Should().BeNull();
            IsTransactionUsable(rootTx.GetDbTransaction()).Should().BeFalse();
            AssertDbContext.TestEntities.Should().HaveCount(1);
        }
예제 #17
0
        public async Task Should_insert_int_with_streaming_disabled()
        {
            ConfigureModel = builder => builder.ConfigureTempTable <int>();

            var options = new SqlTempTableBulkInsertOptions {
                BulkInsertOptions = { EnableStreaming = false }
            };
            var values = new List <int> {
                1, 2
            };
            var query = await ActDbContext.BulkInsertValuesIntoTempTableAsync(values, options).ConfigureAwait(false);

            var tempTable = await query.ToListAsync().ConfigureAwait(false);

            tempTable.Should()
            .HaveCount(2).And
            .BeEquivalentTo(new TempTable <int>(1), new TempTable <int>(2));
        }
예제 #18
0
        public async Task Should_insert_shadow_properties()
        {
            var testEntity = new TestEntityWithShadowProperties {
                Id = new Guid("40B5CA93-5C02-48AD-B8A1-12BC13313866")
            };

            ActDbContext.Entry(testEntity).Property("ShadowStringProperty").CurrentValue = "value";
            ActDbContext.Entry(testEntity).Property("ShadowIntProperty").CurrentValue    = 42;

            var testEntities = new[] { testEntity };

            await SUT.BulkInsertAsync(testEntities, new SqliteBulkInsertOptions());

            var loadedEntity = await AssertDbContext.TestEntitiesWithShadowProperties.FirstOrDefaultAsync();

            AssertDbContext.Entry(loadedEntity).Property("ShadowStringProperty").CurrentValue.Should().Be("value");
            AssertDbContext.Entry(loadedEntity).Property("ShadowIntProperty").CurrentValue.Should().Be(42);
        }
예제 #19
0
        public async Task Should_insert_specified_properties_only()
        {
            var testEntity = new TestEntity
            {
                Id    = new Guid("40B5CA93-5C02-48AD-B8A1-12BC13313866"),
                Name  = "Name",
                Count = 42,
                PropertyWithBackingField = 7
            };

            testEntity.SetPrivateField(3);
            var testEntities             = new[] { testEntity };
            var idProperty               = typeof(TestEntity).GetProperty(nameof(TestEntity.Id));
            var countProperty            = typeof(TestEntity).GetProperty(nameof(TestEntity.Count));
            var propertyWithBackingField = typeof(TestEntity).GetProperty(nameof(TestEntity.PropertyWithBackingField));
            var privateField             = typeof(TestEntity).GetField("_privateField", BindingFlags.Instance | BindingFlags.NonPublic);

            await _sut.BulkInsertAsync(ActDbContext,
                                       ActDbContext.GetEntityType <TestEntity>(),
                                       testEntities,
                                       new SqlBulkInsertOptions
            {
                EntityMembersProvider = new EntityMembersProvider(new MemberInfo[]
                {
                    idProperty,
                    countProperty,
                    propertyWithBackingField,
                    privateField
                })
            });

            var loadedEntities = await AssertDbContext.TestEntities.ToListAsync();

            loadedEntities.Should().HaveCount(1);
            var loadedEntity = loadedEntities[0];

            loadedEntity.Should().BeEquivalentTo(new TestEntity
            {
                Id    = new Guid("40B5CA93-5C02-48AD-B8A1-12BC13313866"),
                Count = 42,
                PropertyWithBackingField = 7
            });
            loadedEntity.GetPrivateField().Should().Be(3);
        }
예제 #20
0
        public void Should_rollback_uncompleted_child_transaction()
        {
            var rootTx  = SUT.BeginTransaction();
            var childTx = SUT.BeginTransaction();

            ActDbContext.Add(new TestEntity());
            ActDbContext.SaveChanges();

            childTx.Dispose();

            SUT.CurrentTransaction.Should().Be(rootTx);
            IsTransactionUsable(rootTx.GetDbTransaction()).Should().BeTrue();
            AssertDbContext.TestEntities.Should().HaveCount(1);

            rootTx.Dispose();

            SUT.CurrentTransaction.Should().BeNull();
            IsTransactionUsable(rootTx.GetDbTransaction()).Should().BeFalse();
            AssertDbContext.TestEntities.Should().HaveCount(0);
        }
예제 #21
0
        public async Task Should_insert_nullable_int_of_entity_with_a_key()
        {
            ConfigureModel = builder =>
            {
                var entityBuilder = builder.ConfigureTempTable <int?>(false);
                entityBuilder.HasKey(t => t.Column1);
                entityBuilder.Property(t => t.Column1).ValueGeneratedNever();
            };

            var values = new List <int?> {
                1, 2
            };

            await using var query = await ActDbContext.BulkInsertValuesIntoTempTableAsync(values, new SqlServerTempTableBulkInsertOptions { PrimaryKeyCreation = PrimaryKeyPropertiesProviders.None });

            var tempTable = await query.Query.ToListAsync();

            tempTable.Should()
            .HaveCount(2).And
            .BeEquivalentTo(new TempTable <int?>(1), new TempTable <int?>(2));
        }
예제 #22
0
        public async Task Should_create_primary_key_for_entityType()
        {
            await using var tempTableReference = await ArrangeDbContext.CreateTempTableAsync <TestEntity>(new TempTableCreationOptions
            {
                TableNameProvider  = DefaultTempTableNameProvider.Instance,
                PrimaryKeyCreation = PrimaryKeyPropertiesProviders.None
            });

            var entityType = ActDbContext.GetEntityType <TestEntity>();
            await SUT.CreatePrimaryKeyAsync(ActDbContext, PrimaryKeyPropertiesProviders.AdaptiveForced.GetPrimaryKeyProperties(entityType, entityType.GetProperties().ToList()), tempTableReference.Name);

            var constraints = await AssertDbContext.GetTempTableConstraints <TestEntity>().ToListAsync();

            constraints.Should().HaveCount(1)
            .And.Subject.First().CONSTRAINT_TYPE.Should().Be("PRIMARY KEY");

            var keyColumns = await AssertDbContext.GetTempTableKeyColumns <TestEntity>().ToListAsync();

            keyColumns.Should().HaveCount(1)
            .And.Subject.First().COLUMN_NAME.Should().Be(nameof(TestEntity.Id));
        }