using System.Collections.Generic;
using System.Data.SqlClient;
public static void Main()
var dsGeneratedInvoices = GenerateInvoices(5, 3);
var dtInvoices = dsGeneratedInvoices.Tables[0];
var dtInvoiceItems = dsGeneratedInvoices.Tables[1];
using (var connection = new SqlConnection(FiddleHelper.GetConnectionStringSqlServer()))
ShowData(connection, "Before");
using (var bulk = new BulkOperation(connection))
bulk.DestinationTableName = "Invoices";
bulk.AutoMapOutputIdentity = true;
bulk.BulkMerge(dtInvoices);
using (var bulk = new BulkOperation(connection))
dtInvoiceItems.AsEnumerable().ToList().ForEach(x => x["InvoiceID"] = ((DataRow)x["InvoiceReference"])["InvoiceID"]);
bulk.DestinationTableName = "InvoiceItems";
bulk.BulkMerge(dtInvoiceItems);
ShowData(connection, "After");
public static void ShowData(SqlConnection connection, string text)
using (var command = connection.CreateCommand())
SELECT * FROM InvoiceItems
var sqlDataAdapter = new SqlDataAdapter(command);
ds.Tables[0].TableName = "2 - Invoices " + text;
ds.Tables[1].TableName = "3 - InvoiceItems " + text;
FiddleHelper.WriteTable(ds.Tables[0]);
FiddleHelper.WriteTable(ds.Tables[1]);
public static DataSet GenerateInvoices(int countInvoice, int countInvoiceItem, bool useOld = false)
DataSet dataSet = new DataSet();
var dtInvoices = new DataTable("Invoice");
dtInvoices.Columns.Add("InvoiceID", typeof(int));
dtInvoices.Columns.Add("Number", typeof(string));
dataSet.Tables.Add(dtInvoices);
var dtInvoiceItems = new DataTable("InvoiceItems");
dtInvoiceItems.Columns.Add("InvoiceItemID", typeof(int));
dtInvoiceItems.Columns.Add("ProductName", typeof(string));
dtInvoiceItems.Columns.Add("InvoiceID", typeof(int));
dtInvoiceItems.Columns.Add("InvoiceReference", typeof(object));
dataSet.Tables.Add(dtInvoiceItems);
for(int i = 0; i < countInvoice; i++)
var drInvoice = dtInvoices.NewRow();
drInvoice["InvoiceID"] = (i + 1);
drInvoice["Number"] = (useOld ? "Old_" : "") + "Number_" + i;
dtInvoices.Rows.Add(drInvoice);
for(int j = 0; j < countInvoiceItem; j++)
var drInvoiceItem = dtInvoiceItems.NewRow();
drInvoiceItem["InvoiceItemID"] = (i * countInvoiceItem) + (j + 1);
drInvoiceItem["ProductName"] = (useOld ? "Old_" : "") + "ProductName_" + i + "_" + j;
drInvoiceItem["InvoiceReference"] = drInvoice;
dtInvoiceItems.Rows.Add(drInvoiceItem);
public static void SeedInvoices(int countInvoice, int countInvoiceItem)
var dsGeneratedInvoices = GenerateInvoices(countInvoice, countInvoiceItem, true);
var dtInvoices = dsGeneratedInvoices.Tables[0];
var dtInvoiceItems = dsGeneratedInvoices.Tables[1];
using (var connection = new SqlConnection(FiddleHelper.GetConnectionStringSqlServer()))
using (var bulk = new BulkOperation(connection))
bulk.DestinationTableName = "Invoices";
bulk.ColumnMappings.Add("InvoiceID", ColumnMappingDirectionType.Output);
bulk.ColumnMappings.Add("Number", ColumnMappingDirectionType.Input);
bulk.BulkInsert(dtInvoices);
using (var bulk = new BulkOperation(connection))
dtInvoiceItems.AsEnumerable().ToList().ForEach(x => x["InvoiceID"] = ((DataRow)x["InvoiceReference"])["InvoiceID"]);
bulk.DestinationTableName = "InvoiceItems";
bulk.BulkInsert(dtInvoiceItems);
public static void GenerateDatabase()
using (var connection = new SqlConnection(FiddleHelper.GetConnectionStringSqlServer()))
using (var command = connection.CreateCommand())
[InvoiceID] [INT] IDENTITY(1,1) NOT NULL,
[Number] [NVARCHAR](MAX) NULL,
CONSTRAINT [PK_Invoices] PRIMARY KEY CLUSTERED
CREATE TABLE [InvoiceItems]
[InvoiceItemID] [INT] IDENTITY(1,1) NOT NULL,
[ProductName] [NVARCHAR](MAX) NULL,
CONSTRAINT [PK_InvoiceItems] PRIMARY KEY CLUSTERED
ALTER TABLE [InvoiceItems] WITH CHECK ADD CONSTRAINT [FK_InvoiceItems_InvoiceID] FOREIGN KEY([InvoiceID])
REFERENCES [Invoices] ([InvoiceID])
command.ExecuteNonQuery();