ADO - ADO.NET Bulk Operations

Bulk operations are used to insert or update very large volumes of data efficiently with minimal database round trips.

In ADO.NET, this is mainly done using SqlBulkCopy.


Why bulk operations exist

Row-by-row inserts are slow because:

  • Each insert = network round trip

  • Each insert = logging + locking overhead

Bulk operations send data in batches, drastically improving performance.


Core class: SqlBulkCopy

Used to copy data from:

  • DataTable

  • DataReader

  • CSV (via reader)

  • In-memory collections (after conversion)

Directly into a SQL Server table


Basic example

using (SqlConnection conn = new SqlConnection(cs))
{
    conn.Open();

    using (SqlBulkCopy bulk = new SqlBulkCopy(conn))
    {
        bulk.DestinationTableName = "dbo.Users";
        bulk.WriteToServer(dataTable);
    }
}

✔ Inserts thousands/millions of rows
✔ One database call
✔ Very fast


Column mapping (mandatory in real projects)

bulk.ColumnMappings.Add("UserId", "Id");
bulk.ColumnMappings.Add("UserName", "Name");
bulk.ColumnMappings.Add("Email", "Email");

Rule: source column name ≠ destination column name → mapping required


Batch size & timeout (performance tuning)

bulk.BatchSize = 5000;
bulk.BulkCopyTimeout = 60;

Why this matters

  • BatchSize limits rows per transaction

  • Prevents long locks

  • Reduces rollback size on failure


Using DataReader (best for large files)

using (SqlCommand cmd = new SqlCommand("SELECT * FROM TempUsers", conn))
using (SqlDataReader reader = cmd.ExecuteReader())
{
    bulk.WriteToServer(reader);
}

✔ Streams data
✔ Minimal memory usage
✔ Best for very large datasets


Bulk operations + Transactions

SqlTransaction tx = conn.BeginTransaction();

using (SqlBulkCopy bulk = new SqlBulkCopy(conn, SqlBulkCopyOptions.Default, tx))
{
    bulk.DestinationTableName = "Orders";
    bulk.WriteToServer(table);
}

tx.Commit();

✔ All-or-nothing bulk insert
✔ Rollback supported


Important SqlBulkCopyOptions

Option Use
KeepIdentity Preserve identity values
TableLock Faster, but locks table
CheckConstraints Enforces constraints
FireTriggers Executes triggers

Example:

new SqlBulkCopy(conn, SqlBulkCopyOptions.TableLock, tx)

Common failures & causes

Error Reason
Column mismatch Missing mapping
Timeout No batch size
Identity error Forgot KeepIdentity
Deadlock Large batch + no TableLock

When NOT to use bulk operations

  • Small data (<100 rows)

  • Business logic per row is required

  • Triggers must run for every insert (unless FireTriggers)


Real performance numbers (approx)

Method 100k rows
Insert loop 30–60 sec
SqlBulkCopy < 1 sec

ADO.NET bulk operations (SqlBulkCopy) allow extremely fast, transactional, large-scale data insertion by minimizing network and logging overhead.

  •