Exemple #1
0
        private void DestinationAndSourceTableNameTest(DbServer dbServer)
        {
            ContextUtil.DbServer = dbServer;
            using var context    = new TestContext(ContextUtil.GetOptions());

            context.Truncate <Entry>();
            context.Truncate <EntryPrep>();
            context.Truncate <EntryArchive>();

            var entities = new List <Entry>();

            for (int i = 1; i <= 10; i++)
            {
                var entity = new Entry
                {
                    Name = "Name " + i,
                };
                entities.Add(entity);
            }
            // [DEST]
            context.BulkInsert(entities, b => b.CustomDestinationTableName = nameof(EntryArchive)); // Insert into table 'EntryArchive'
            Assert.Equal(10, context.EntryArchives.Count());

            // [SOURCE] (With CustomSourceTableName list not used so can be empty)
            context.BulkInsert(new List <Entry>(), b => b.CustomSourceTableName = nameof(EntryArchive)); // InsertOrMERGE from table 'EntryArchive' into table 'Entry'
            Assert.Equal(10, context.Entries.Count());

            var entities2 = new List <EntryPrep>();

            for (int i = 1; i <= 20; i++)
            {
                var entity = new EntryPrep
                {
                    NameInfo = "Name Info " + i,
                };
                entities2.Add(entity);
            }
            context.EntryPreps.AddRange(entities2);
            context.SaveChanges();

            var mappings = new Dictionary <string, string>();

            mappings.Add(nameof(EntryPrep.EntryPrepId), nameof(Entry.EntryId)); // here used 'nameof(Prop)' since Columns have the same name as Props
            mappings.Add(nameof(EntryPrep.NameInfo), nameof(Entry.Name));       // if columns they were different name then they would be set with string names, eg. "EntryPrepareId"
            var bulkConfig = new BulkConfig {
                CustomSourceTableName = nameof(EntryPrep),
                CustomSourceDestinationMappingColumns = mappings,
                //UpdateByProperties = new List<string> { "Name" } // with this all are insert since names are different
            };

            // [SOURCE]
            context.BulkInsertOrUpdate(new List <Entry>(), bulkConfig); // InsertOrMERGE from table 'EntryPrep' into table 'Entry'
            Assert.Equal(20, context.Entries.Count());
        }
 private void InsertAndUpdateWithCompositeKey(DbServer databaseType)
 {
     ContextUtil.DbServer = databaseType;
     using (var context = new TestContext(ContextUtil.GetOptions()))
     {
         context.Truncate <UserRole>();
         var entities = new List <UserRole>();
         for (int i = 0; i < EntitiesNumber; i++)
         {
             entities.Add(new UserRole
             {
                 UserId      = i / 10,
                 RoleId      = i % 10,
                 Description = "desc"
             });
         }
         context.BulkInsert(entities);
     }
     using (var context = new TestContext(ContextUtil.GetOptions()))
     {
         var entities      = context.UserRoles.ToList();
         int entitiesCount = entities.Count();
         for (int i = 0; i < entitiesCount; i++)
         {
             entities[i].Description = "desc updated " + i;
         }
         context.BulkUpdate(entities);
     }
     using (var context = new TestContext(ContextUtil.GetOptions()))
     {
         var entities = context.UserRoles.ToList();
         Assert.Equal(EntitiesNumber, entities.Count());
         context.BulkDelete(entities);
     }
 }
Exemple #3
0
        [InlineData(DbServer.SQLite)] // Does NOT have Computed Columns
        private void ComputedAndDefaultValuesTest(DbServer dbServer)
        {
            ContextUtil.DbServer = dbServer;
            using var context    = new TestContext(ContextUtil.GetOptions());
            context.Truncate <Document>();
            bool isSqlite = dbServer == DbServer.SQLite;

            var entities = new List <Document>();

            for (int i = 1; i <= EntitiesNumber; i++)
            {
                var entity = new Document
                {
                    Content = "Info " + i
                };
                if (isSqlite)
                {
                    entity.DocumentId    = Guid.NewGuid();
                    entity.ContentLength = entity.Content.Length;
                }
                entities.Add(entity);
            }
            context.BulkInsert(entities, bulkAction => bulkAction.SetOutputIdentity = true); // example of setting BulkConfig with Action argument

            var firstDocument = context.Documents.AsNoTracking().FirstOrDefault();
            var count         = context.Documents.Count();

            // TEST

            Assert.Equal("DefaultData", firstDocument.Tag);

            firstDocument.Tag = null;
            var upsertList = new List <Document> {
                //firstDocument, // GetPropertiesWithDefaultValue .SelectMany(
                new Document {
                    Content = "Info " + (count + 1)
                },                                                // to test adding new with InsertOrUpdate (entity having Guid DbGenerated)
                new Document {
                    Content = "Info " + (count + 2)
                }
            };

            if (isSqlite)
            {
                upsertList[0].DocumentId = Guid.NewGuid(); //[1]
                upsertList[1].DocumentId = Guid.NewGuid(); //[2]
            }
            count += 2;

            context.BulkInsertOrUpdate(upsertList);
            firstDocument = context.Documents.AsNoTracking().FirstOrDefault();
            var entitiesCount = context.Documents.Count();

            //Assert.Null(firstDocument.Tag); // OnUpdate columns with Defaults not omitted, should change even to default value, in this case to 'null'

            Assert.NotEqual(Guid.Empty, firstDocument.DocumentId);
            Assert.Equal(true, firstDocument.IsActive);
            Assert.Equal(firstDocument.Content.Length, firstDocument.ContentLength);
            Assert.Equal(entitiesCount, count);
        }
        private void UpdateSetting(SettingsEnum settings, object value)
        {
            using (var context = new TestContext(ContextUtil.GetOptions()))
            {
                context.Truncate <Setting>();
            }

            using (var context = new TestContext(ContextUtil.GetOptions()))
            {
                context.Settings.Add(new Setting()
                {
                    Settings = SettingsEnum.Sett1, Value = "Val1"
                });
                context.SaveChanges();
            }

            using (var context = new TestContext(ContextUtil.GetOptions()))
            {
                // can work with explicit value: .Where(x => x.Settings == SettingsEnum.Sett1) or if named Parameter used then it has to be named (settings) same as Property (Settings) - Case not relevant, it is CaseInsensitive
                context.Settings.Where(x => x.Settings == settings).BatchUpdate(x => new Setting {
                    Value = value.ToString()
                });
            }

            using (var context = new TestContext(ContextUtil.GetOptions()))
            {
                context.Truncate <Setting>();
            }
        }
        private void RunBatchUpdateEnum(DbServer dbServer)
        {
            using var context = new TestContext(ContextUtil.GetOptions());

            context.Truncate <Source>();

            context.Sources.AddRange(new Source[] {
                new Source {
                    StatusId = Status.Init, TypeId = Type.Type2
                },
                new Source {
                    StatusId = Status.Changed, TypeId = Type.Type2
                }
            });
            context.SaveChanges();

            var updateValues = new Source()
            {
                StatusId = Status.Changed
            };
            var updateColumns = new List <string>()
            {
                nameof(updateValues.StatusId)
            };

            context.Sources.Where(e => e.StatusId == Status.Init).BatchUpdate(updateValues, updateColumns);

            Assert.Equal(Type.Type2, context.Sources.FirstOrDefault().TypeId); // Should remain 'Type.Type2' and not be changed to default 'Type.Undefined'
        }
        [InlineData(DbServer.Sqlite)] // Does NOT have Computed Columns
        private void ComputedAndDefaultValuesTest(DbServer dbServer)
        {
            ContextUtil.DbServer = dbServer;
            using var context    = new TestContext(ContextUtil.GetOptions());
            context.Truncate <Document>();

            var entities = new List <Document>();

            for (int i = 1; i <= EntitiesNumber; i++)
            {
                var entity = new Document
                {
                    Content = "Info " + i
                };
                if (dbServer == DbServer.Sqlite)
                {
                    entity.DocumentId    = Guid.NewGuid();
                    entity.ContentLength = entity.Content.Length;
                }
                entities.Add(entity);
            }
            context.BulkInsert(entities, bulkAction => bulkAction.SetOutputIdentity = true); // example of setting BulkConfig with Action argument

            // TEST
            var documents = context.Documents.ToList();

            Assert.Equal(EntitiesNumber, documents.Count());
            var firstDocument = documents[0];

            Assert.NotEqual(Guid.Empty, firstDocument.DocumentId);
            Assert.Equal(firstDocument.Content.Length, firstDocument.ContentLength);
            Assert.Equal(true, firstDocument.IsActive);
        }
Exemple #7
0
        //[InlineData(DbServer.Sqlite)] // No TimeStamp column type but can be set with DefaultValueSql: "CURRENT_TIMESTAMP" as it is in OnModelCreating() method.
        private void TimeStampTest(DbServer dbServer)
        {
            ContextUtil.DbServer = dbServer;
            using var context    = new TestContext(ContextUtil.GetOptions());

            context.Truncate <File>();

            var entities = new List <File>();

            for (int i = 1; i <= EntitiesNumber; i++)
            {
                var entity = new File
                {
                    Data = "Some data " + i
                };
                entities.Add(entity);
            }
            context.BulkInsert(entities, bulkAction => bulkAction.SetOutputIdentity = true); // example of setting BulkConfig with Action argument

            // For testing concurrency conflict (UPDATE changes RowVersion which is TimeStamp column)
            context.Database.ExecuteSqlRaw("UPDATE dbo.[File] SET Data = 'Some data 1 PRE CHANGE' WHERE [Id] = 1;");

            var entitiesToUpdate = entities.Take(10).ToList();

            foreach (var entityToUpdate in entitiesToUpdate)
            {
                entityToUpdate.Data += " UPDATED";
            }

            using var transaction = context.Database.BeginTransaction();
            var bulkConfig = new BulkConfig {
                SetOutputIdentity = true, DoNotUpdateIfTimeStampChanged = true
            };

            context.BulkUpdate(entitiesToUpdate, bulkConfig);

            var list = bulkConfig.TimeStampInfo?.EntitiesOutput.Cast <File>().ToList();

            Assert.Equal(9, list.Count());
            Assert.Equal(1, bulkConfig.TimeStampInfo.NumberOfSkippedForUpdate);

            if (bulkConfig.TimeStampInfo?.NumberOfSkippedForUpdate > 0)
            {
                //Options, based on needs:

                // 1. rollback entire Update
                transaction.Rollback(); // 1. rollback entire Update

                // 2. throw Exception
                //throw new DbUpdateConcurrencyException()

                // 3. Update them again

                // 4. Skip them and leave it unchanged
            }
            else
            {
                transaction.Commit();
            }
        }
Exemple #8
0
        private void InsertWithOwnedTypes(DbServer databaseType)
        {
            ContextUtil.DbServer = databaseType;
            using (var context = new TestContext(ContextUtil.GetOptions()))
            {
                if (databaseType == DbServer.SqlServer)
                {
                    context.Truncate <ChangeLog>();
                    context.Database.ExecuteSqlRaw("TRUNCATE TABLE [" + nameof(ChangeLog) + "]");
                }
                else
                {
                    //context.ChangeLogs.BatchDelete(); // TODO
                    context.BulkDelete(context.ChangeLogs.ToList());
                }

                var entities = new List <ChangeLog>();
                for (int i = 1; i <= EntitiesNumber; i++)
                {
                    entities.Add(new ChangeLog
                    {
                        Description = "Dsc " + i,
                        Audit       = new Audit
                        {
                            ChangedBy   = "User" + 1,
                            ChangedTime = DateTime.Now,
                            InfoType    = InfoType.InfoTypeA
                        }/*,
                          * AuditExtended = new AuditExtended
                          * {
                          * CreatedBy = "UserS" + 1,
                          * Remark = "test",
                          * CreatedTime = DateTime.Now
                          * },
                          * AuditExtendedSecond = new AuditExtended
                          * {
                          * CreatedBy = "UserS" + 1,
                          * Remark = "sec",
                          * CreatedTime = DateTime.Now
                          * }*/
                    });
                }
                context.BulkInsert(entities);

                if (databaseType == DbServer.SqlServer)
                {
                    context.BulkRead(
                        entities,
                        new BulkConfig
                    {
                        UpdateByProperties = new List <string> {
                            nameof(Item.Description)
                        }
                    }
                        );
                    Assert.Equal(2, entities[1].ChangeLogId);
                }
            }
        }
        //[InlineData(DbServer.Sqlite)] Not supported
        private void ShadowFKPropertiesTest(DbServer dbServer) // with Foreign Key as Shadow Property
        {
            ContextUtil.DbServer = dbServer;
            using var context    = new TestContext(ContextUtil.GetOptions());

            if (dbServer == DbServer.SqlServer)
            {
                context.Truncate <ItemLink>();
                context.Database.ExecuteSqlRaw("TRUNCATE TABLE [" + nameof(ItemLink) + "]");
            }
            else
            {
                //context.ChangeLogs.BatchDelete(); // TODO
                context.BulkDelete(context.ItemLinks.ToList());
            }
            context.BulkDelete(context.Items.ToList()); // On table with FK Truncate does not work


            for (int i = 1; i < 10; ++i)
            {
                var entity = new Item
                {
                    ItemId        = 0,
                    Name          = "name " + i,
                    Description   = "info " + Guid.NewGuid().ToString().Substring(0, 3),
                    Quantity      = i % 10,
                    Price         = i / (i % 5 + 1),
                    TimeUpdated   = DateTime.Now,
                    ItemHistories = new List <ItemHistory>()
                };

                context.Items.Add(entity);
            }

            context.SaveChanges();
            var items    = context.Items.ToList();
            var entities = new List <ItemLink>();

            for (int i = 0; i <= EntitiesNumber - 1; i++)
            {
                entities.Add(new ItemLink
                {
                    ItemLinkId = 0,
                    Item       = items[i % items.Count]
                });
            }
            context.BulkInsert(entities);

            if (dbServer == DbServer.SqlServer)
            {
                context.BulkRead(entities);
                foreach (var entity in entities)
                {
                    Assert.NotNull(entity.Item);
                }
            }

            context.BulkDelete(context.ItemLinks.ToList());
        }
Exemple #10
0
        private void CompositeKeyTest(DbServer dbServer)
        {
            ContextUtil.DbServer = dbServer;
            using var context    = new TestContext(ContextUtil.GetOptions());

            context.Truncate <UserRole>();

            // INSERT
            var entitiesToInsert = new List <UserRole>();

            for (int i = 0; i < EntitiesNumber; i++)
            {
                entitiesToInsert.Add(new UserRole
                {
                    UserId      = i / 10,
                    RoleId      = i % 10,
                    Description = "desc"
                });
            }
            context.BulkInsert(entitiesToInsert);

            // UPDATE
            var entitiesToUpdate = context.UserRoles.ToList();
            int entitiesCount    = entitiesToUpdate.Count();

            for (int i = 0; i < entitiesCount; i++)
            {
                entitiesToUpdate[i].Description = "desc updated " + i;
            }
            context.BulkUpdate(entitiesToUpdate);

            var entitiesToUpsert = new List <UserRole>()
            {
                new UserRole {
                    UserId = 1, RoleId = 1
                },
                new UserRole {
                    UserId = 2, RoleId = 2
                },
                new UserRole {
                    UserId = 100, RoleId = 10
                },
            };

            // TEST
            var entities = context.UserRoles.ToList();

            Assert.Equal(EntitiesNumber, entities.Count());

            context.BulkInsertOrUpdate(entitiesToUpsert, new BulkConfig {
                PropertiesToInclude = new List <string> {
                    nameof(UserRole.UserId), nameof(UserRole.RoleId)
                }
            });
            var entitiesFinal = context.UserRoles.ToList();

            Assert.Equal(EntitiesNumber + 1, entitiesFinal.Count());
        }
        [InlineData(DbServer.Sqlite)] // Does NOT have Computed Columns
        private void ComputedAndDefaultValuesTest(DbServer dbServer)
        {
            ContextUtil.DbServer = dbServer;
            using var context    = new TestContext(ContextUtil.GetOptions());
            context.Truncate <Document>();

            var entities = new List <Document>();

            for (int i = 1; i <= EntitiesNumber; i++)
            {
                var entity = new Document
                {
                    Content = "Info " + i
                };
                if (dbServer == DbServer.Sqlite)
                {
                    entity.DocumentId    = Guid.NewGuid();
                    entity.ContentLength = entity.Content.Length;
                }
                entities.Add(entity);
            }
            context.BulkInsert(entities, bulkAction => bulkAction.SetOutputIdentity = true); // example of setting BulkConfig with Action argument

            var firstDocument = context.Documents.AsNoTracking().FirstOrDefault();
            var count         = context.Documents.Count();

            // TEST

            Assert.Equal("DefaultData", firstDocument.Tag);

            firstDocument.Tag = null;
            context.BulkInsertOrUpdate(new List <Document> {
                firstDocument
            });
            firstDocument = context.Documents.AsNoTracking().FirstOrDefault();

            Assert.Null(firstDocument.Tag); // OnUpdate columns with Defaults not ommited, should change even to default value, in this case to 'null'

            Assert.NotEqual(Guid.Empty, firstDocument.DocumentId);
            Assert.Equal(true, firstDocument.IsActive);
            Assert.Equal(firstDocument.Content.Length, firstDocument.ContentLength);
            Assert.Equal(EntitiesNumber, count);
        }
Exemple #12
0
        private void DefaultValuesTest(DbServer dbServer)
        {
            ContextUtil.DbServer = dbServer;
            using var context    = new TestContext(ContextUtil.GetOptions());
            context.Truncate <Document>();
            context.Documents.BatchDelete();
            bool isSqlite = dbServer == DbServer.SQLite;

            var entities = new List <Document>()
            {
                new Document {
                    DocumentId = Guid.Parse("15E5936C-8021-45F4-A055-2BE89B065D9E"), Content = "Info " + 1
                },
                new Document {
                    DocumentId = Guid.Parse("00C69E47-A08F-49E0-97A6-56C62C9BB47E"), Content = "Info " + 2
                },
                new Document {
                    DocumentId = Guid.Parse("22CF94AE-20D3-49DE-83FA-90E79DD94706"), Content = "Info " + 3
                },
                new Document {
                    DocumentId = Guid.Parse("B3A2F9A5-4222-47C3-BEEA-BF50771665D3"), Content = "Info " + 4
                },
                new Document {
                    DocumentId = Guid.Parse("12AF6361-95BC-44F3-A487-C91C440018D8"), Content = "Info " + 5
                },
            };
            var firstDocumentUp = entities.FirstOrDefault();

            context.BulkInsertOrUpdate(entities, bulkConfig => bulkConfig.SetOutputIdentity = true); // example of setting BulkConfig with Action argument

            var firstDocument = context.Documents.AsNoTracking().OrderBy(x => x.Content).FirstOrDefault();

            var countDb       = context.Documents.Count();
            var countEntities = entities.Count();

            // TEST

            Assert.Equal(countDb, countEntities);

            Assert.Equal(firstDocument.DocumentId, firstDocumentUp.DocumentId);
        }
Exemple #13
0
        [InlineData(DbServer.SQLite)] // Does NOT have Computed Columns
        private void ParameterlessConstructorTest(DbServer dbServer)
        {
            ContextUtil.DbServer = dbServer;
            using var context    = new TestContext(ContextUtil.GetOptions());
            context.Truncate <Letter>();

            var entities = new List <Letter>();
            int counter  = 10;

            for (int i = 1; i <= counter; i++)
            {
                var entity = new Letter("Note " + i);
                entities.Add(entity);
            }
            context.BulkInsert(entities);

            var count             = context.Letters.Count();
            var firstDocumentNote = context.Letters.AsNoTracking().FirstOrDefault();

            // TEST
            Assert.Equal(counter, count);
            Assert.Equal("Note 1", firstDocumentNote.Note);
        }
Exemple #14
0
        private void CompositeKeyTest(DbServer dbServer)
        {
            ContextUtil.DbServer = dbServer;
            using var context    = new TestContext(ContextUtil.GetOptions());

            context.Truncate <UserRole>();

            // INSERT
            var entitiesToInsert = new List <UserRole>();

            for (int i = 0; i < EntitiesNumber; i++)
            {
                entitiesToInsert.Add(new UserRole
                {
                    UserId      = i / 10,
                    RoleId      = i % 10,
                    Description = "desc"
                });
            }
            context.BulkInsert(entitiesToInsert);

            // UPDATE
            var entitiesToUpdate = context.UserRoles.ToList();
            int entitiesCount    = entitiesToUpdate.Count();

            for (int i = 0; i < entitiesCount; i++)
            {
                entitiesToUpdate[i].Description = "desc updated " + i;
            }
            context.BulkUpdate(entitiesToUpdate);

            // TEST
            var entities = context.UserRoles.ToList();

            Assert.Equal(EntitiesNumber, entities.Count());
        }
Exemple #15
0
        public void BatchConverterTest(DbServer dbServer)
        {
            ContextUtil.DbServer = dbServer;

            using var context = new TestContext(ContextUtil.GetOptions());
            context.Truncate <Info>();

            var currentDate = DateTime.Today;
            var entity      = new Info {
                Message = "name A", DateTimeOff = currentDate
            };

            context.Infos.Add(entity);
            context.SaveChanges();

            var updateTo = new Info {
                Message = "name B Updated"
            };

            context.Infos.BatchUpdate(updateTo);

            using var contextRead = new TestContext(ContextUtil.GetOptions());
            Assert.Equal(currentDate, contextRead.Infos.First().DateTimeOff);
        }
Exemple #16
0
        private void TablePerTypeInsertTest()
        {
            ContextUtil.DbServer = DbServer.SQLServer;
            using var context    = new TestContext(ContextUtil.GetOptions());

            context.LogPersonReports.Add(new LogPersonReport {
            });                                                    // used for initial add so that after RESEED it starts from 1, not 0
            context.SaveChanges();
            context.Truncate <LogPersonReport>();
            context.Database.ExecuteSqlRaw($"DELETE FROM {nameof(Log)}");
            context.Database.ExecuteSqlRaw($"DBCC CHECKIDENT('{nameof(Log)}', RESEED, 0);");

            int nextLogId           = GetLastRowId(context, tableName: nameof(Log));
            int numberOfNewToInsert = 1000;

            var entities = new List <LogPersonReport>();

            for (int i = 1; i <= numberOfNewToInsert; i++)
            {
                nextLogId++; // OPTION 1.
                var entity = new LogPersonReport
                {
                    LogId       = nextLogId, // OPTION 1.
                    PersonId    = (i % 22),
                    RegBy       = 15,
                    CreatedDate = DateTime.Now,

                    ReportId = (i % 22) * 10,
                    LogPersonReportTypeId = 4,
                };
                entities.Add(entity);
            }

            var bulkConfigBase = new BulkConfig
            {
                SqlBulkCopyOptions  = Microsoft.Data.SqlClient.SqlBulkCopyOptions.KeepIdentity, // OPTION 1. - to ensure insert order is kept the same since SqlBulkCopy does not guarantee it.
                PropertiesToInclude = new List <string>
                {
                    nameof(LogPersonReport.LogId),
                    nameof(LogPersonReport.PersonId),
                    nameof(LogPersonReport.RegBy),
                    nameof(LogPersonReport.CreatedDate)
                }
            };
            var bulkConfig = new BulkConfig
            {
                PropertiesToInclude = new List <string> {
                    nameof(LogPersonReport.LogId),
                    nameof(LogPersonReport.ReportId),
                    nameof(LogPersonReport.LogPersonReportTypeId)
                }
            };

            context.BulkInsert(entities, bulkConfigBase, type: typeof(Log)); // to base 'Log' table

            //foreach(var entity in entities) { // OPTION 2. Could be set here if Id of base table Log was set by Db (when Op.2. used 'Option 1.' have to be commented out)
            //    entity.LogId = ++nextLogId;
            //}

            context.BulkInsert(entities, bulkConfig); // to 'LogPersonReport' table

            Assert.Equal(nextLogId, context.LogPersonReports.OrderByDescending(a => a.LogId).FirstOrDefault().LogId);
        }
Exemple #17
0
        private void OwnedTypesTest(DbServer dbServer)
        {
            ContextUtil.DbServer = dbServer;
            using var context    = new TestContext(ContextUtil.GetOptions());

            if (dbServer == DbServer.SQLServer)
            {
                context.Truncate <ChangeLog>();
                context.Database.ExecuteSqlRaw("TRUNCATE TABLE [" + nameof(ChangeLog) + "]");
            }
            else
            {
                //context.ChangeLogs.BatchDelete(); // TODO
                context.BulkDelete(context.ChangeLogs.ToList());
            }

            var entities = new List <ChangeLog>();

            for (int i = 1; i <= EntitiesNumber; i++)
            {
                entities.Add(new ChangeLog
                {
                    Description = "Dsc " + i,
                    Audit       = new Audit
                    {
                        ChangedBy   = "User" + 1,
                        ChangedTime = DateTime.Now,
                        InfoType    = InfoType.InfoTypeA
                    },
                    AuditExtended = new AuditExtended
                    {
                        CreatedBy   = "UserS" + 1,
                        Remark      = "test",
                        CreatedTime = DateTime.Now
                    },
                    AuditExtendedSecond = new AuditExtended
                    {
                        CreatedBy   = "UserS" + 1,
                        Remark      = "sec",
                        CreatedTime = DateTime.Now
                    }
                });
            }
            context.BulkInsert(entities);

            if (dbServer == DbServer.SQLServer)
            {
                context.BulkRead(
                    entities,
                    new BulkConfig
                {
                    UpdateByProperties = new List <string> {
                        nameof(Item.Description)
                    }
                }
                    );
                Assert.Equal(2, entities[1].ChangeLogId);
            }

            // TEST
            entities[0].Description   += " UPD";
            entities[0].Audit.InfoType = InfoType.InfoTypeB;
            context.BulkUpdate(entities);
            if (dbServer == DbServer.SQLServer)
            {
                context.BulkRead(entities);
            }
            Assert.Equal("Dsc 1 UPD", entities[0].Description);
            Assert.Equal(InfoType.InfoTypeB, entities[0].Audit.InfoType);
        }