public async Task Import_RecordIsImported() { const string streetName = "Just imported street name"; await DeleteIfExistsByName(streetName); var address = new Address { StreetName = streetName, HouseNumber = 320, PostalCode = "Some postal code", ExtraHouseNumber = 1456, Duration = new NpgsqlTypes.NpgsqlRange <DateTime>(DateTime.Now, DateTime.Now) }; var bulkImport = new NpgsqlBulkUploader(CreateContext()); bulkImport.Import(new[] { address }); var assertContext = CreateContext(); var actualAddress = await assertContext.Addresses .SingleAsync(x => x.StreetName == streetName); using (assertContext) { actualAddress.StreetName.Should().Be(address.StreetName); actualAddress.HouseNumber.Should().Be(address.HouseNumber); actualAddress.PostalCode.Should().Be(address.PostalCode); actualAddress.ExtraHouseNumber.Should().Be(address.ExtraHouseNumber); actualAddress.Duration.ToString().Should().Be(address.Duration.ToString()); } }
static void Main(string[] args) { var streets = new[] { "First", "Second", "Third" }; var codes = new[] { "001001", "002002", "003003", "004004" }; var extraNumbers = new int?[] { null, 1, 2, 3, 5, 8, 13, 21, 34 }; var optionsBuilder = new DbContextOptionsBuilder <BulkContext>(); optionsBuilder.UseNpgsql(Configuration.ConnectionString); var context = new BulkContext(optionsBuilder.Options); context.Database.ExecuteSqlCommand("TRUNCATE addresses CASCADE"); var data = Enumerable.Range(0, 100000) .Select((x, i) => new Address() { StreetName = streets[i % streets.Length], HouseNumber = i + 1, PostalCode = codes[i % codes.Length], ExtraHouseNumber = extraNumbers[i % extraNumbers.Length], Duration = new NpgsqlTypes.NpgsqlRange <DateTime>(DateTime.Now, DateTime.Now) }).ToList(); var uploader = new NpgsqlBulkUploader(context); context.Attach(data[0]); var sw = Stopwatch.StartNew(); uploader.Insert(data); sw.Stop(); Console.WriteLine($"Dynamic solution inserted {data.Count} records for {sw.Elapsed }"); Trace.Assert(context.Addresses.Count() == data.Count); context.Database.ExecuteSqlCommand("TRUNCATE addresses CASCADE"); TestViaInterfaceCase(data, context); data.ForEach(x => x.HouseNumber += 1); sw = Stopwatch.StartNew(); uploader.Update(data); sw.Stop(); Console.WriteLine($"Dynamic solution updated {data.Count} records for {sw.Elapsed }"); context.Database.ExecuteSqlCommand("TRUNCATE addresses CASCADE"); sw = Stopwatch.StartNew(); uploader.Import(data); sw.Stop(); Console.WriteLine($"Dynamic solution imported {data.Count} records for {sw.Elapsed }"); // With transaction context.Database.ExecuteSqlCommand("TRUNCATE addresses CASCADE"); using (var transaction = new TransactionScope()) { uploader.Insert(data); } Trace.Assert(context.Addresses.Count() == 0); sw = Stopwatch.StartNew(); uploader.Update(data); sw.Stop(); Console.WriteLine($"Dynamic solution updated {data.Count} records for {sw.Elapsed } (after transaction scope)"); TestAsync(context, uploader, data).Wait(); Console.ReadLine(); }
static void Main(string[] args) { var optionsBuilder = new DbContextOptionsBuilder<BulkContext>(); optionsBuilder.UseNpgsql(Configuration.ConnectionString); var context = new BulkContext(optionsBuilder.Options); context.Database.Migrate(); context.Database.ExecuteSqlRaw("TRUNCATE addresses CASCADE"); var data = Enumerable.Range(0, 100000) .Select((x, i) => new Address() { StreetName = streets[i % streets.Length], HouseNumber = i + 1, PostalCode = codes[i % codes.Length], ExtraHouseNumber = extraNumbers[i % extraNumbers.Length], Duration = new NpgsqlTypes.NpgsqlRange<DateTime>(DateTime.Now, DateTime.Now), AddressType = i % 2 == 0 ? AddressType.Type1 : AddressType.Type2, AddressTypeInt = i % 2 == 0 ? AddressTypeInt.First : AddressTypeInt.Second, UnmappedEnum = i % 2 == 0 ? UnmappedEnum.A : UnmappedEnum.B, }).ToList(); var uploader = new NpgsqlBulkUploader(context); context.Attach(data[0]); data[0].AddressId = 11; data[1].CreatedAt = DateTime.Now; //context.Add(data[0]); //context.Add(data[1]); //context.SaveChanges(); // data.ForEach(x => x.StreetName = null); var sw = Stopwatch.StartNew(); uploader.Insert(data); sw.Stop(); Console.WriteLine($"Dynamic solution inserted {data.Count} records for {sw.Elapsed }"); // CompareValues(data, new BulkContext(optionsBuilder.Options)); context.Database.ExecuteSqlRaw("TRUNCATE addresses CASCADE"); TestViaInterfaceCase(data, context); data.ForEach(x => x.HouseNumber += 1); sw = Stopwatch.StartNew(); uploader.Update(data); sw.Stop(); Console.WriteLine($"Dynamic solution updated {data.Count} records for {sw.Elapsed }"); context.Database.ExecuteSqlRaw("TRUNCATE addresses CASCADE"); sw = Stopwatch.StartNew(); uploader.Import(data); sw.Stop(); Console.WriteLine($"Dynamic solution imported {data.Count} records for {sw.Elapsed }"); // With transaction context.Database.ExecuteSqlRaw("TRUNCATE addresses CASCADE"); using (var transaction = new TransactionScope()) { uploader.Insert(data); } // Trace.Assert(context.Addresses.Count() == 0); sw = Stopwatch.StartNew(); uploader.Update(data); sw.Stop(); Console.WriteLine($"Dynamic solution updated {data.Count} records for {sw.Elapsed } (after transaction scope)"); TestAsync(context, uploader, data).Wait(); TestDerived(context); Console.WriteLine(); Console.WriteLine("Time to press any key..."); Console.ReadLine(); }