EntityFrameworkCore.SqlServer.SimpleBulks
A very simple .net core library that can help to sync a large number of records in-memory into the database using the SqlBulkCopy class.
Overview
This library provides extension methods so that you can use with your EntityFrameworkCore DbContext instance DbContextExtensions.cs or you can use SqlConnectionExtensions.cs to work directly with a SqlConnection instance without using EntityFrameworkCore.
Nuget
| Database | Package | GitHub |
|---|---|---|
| SQL Server | EntityFrameworkCore.SqlServer.SimpleBulks | EntityFrameworkCore.SqlServer.SimpleBulks |
| PostgreSQL | EntityFrameworkCore.PostgreSQL.SimpleBulks | EntityFrameworkCore.PostgreSQL.SimpleBulks |
| MySQL | EntityFrameworkCore.MySQL.SimpleBulks | EntityFrameworkCore.MySQL.SimpleBulks |
Features
- Bulk Insert
- Bulk Update
- Bulk Delete
- Bulk Merge
- Bulk Match
- Temp Table
- Direct Insert
- Direct Update
- Direct Delete
Examples
EntityFrameworkCore.SqlServer.SimpleBulks.Demo
- Update the connection string:
private const string _connectionString = "Server=.;Database=SimpleBulks;User Id=xxx;Password=xxx";
- Build and run.
DbContextExtensions
Using Lambda Expression
using EntityFrameworkCore.SqlServer.SimpleBulks.BulkDelete;
using EntityFrameworkCore.SqlServer.SimpleBulks.BulkInsert;
using EntityFrameworkCore.SqlServer.SimpleBulks.BulkMerge;
using EntityFrameworkCore.SqlServer.SimpleBulks.BulkUpdate;
// Insert all columns
dbct.BulkInsert(rows);
dbct.BulkInsert(compositeKeyRows);
// Insert selected columns only
dbct.BulkInsert(rows,
row => new { row.Column1, row.Column2, row.Column3 });
dbct.BulkInsert(compositeKeyRows,
row => new { row.Id1, row.Id2, row.Column1, row.Column2, row.Column3 });
dbct.BulkUpdate(rows,
row => new { row.Column3, row.Column2 });
dbct.BulkUpdate(compositeKeyRows,
row => new { row.Column3, row.Column2 });
dbct.BulkMerge(rows,
row => row.Id,
row => new { row.Column1, row.Column2 },
row => new { row.Column1, row.Column2, row.Column3 });
dbct.BulkMerge(compositeKeyRows,
row => new { row.Id1, row.Id2 },
row => new { row.Column1, row.Column2, row.Column3 },
row => new { row.Id1, row.Id2, row.Column1, row.Column2, row.Column3 });
dbct.BulkDelete(rows);
dbct.BulkDelete(compositeKeyRows);Using Dynamic String
using EntityFrameworkCore.SqlServer.SimpleBulks.BulkDelete;
using EntityFrameworkCore.SqlServer.SimpleBulks.BulkInsert;
using EntityFrameworkCore.SqlServer.SimpleBulks.BulkMerge;
using EntityFrameworkCore.SqlServer.SimpleBulks.BulkUpdate;
dbct.BulkUpdate(rows,
[ "Column3", "Column2" ]);
dbct.BulkUpdate(compositeKeyRows,
[ "Column3", "Column2" ]);
dbct.BulkMerge(rows,
"Id",
[ "Column1", "Column2" ],
[ "Column1", "Column2", "Column3" ]);
dbct.BulkMerge(compositeKeyRows,
[ "Id1", "Id2" ],
[ "Column1", "Column2", "Column3" ],
[ "Id1", "Id2", "Column1", "Column2", "Column3" ]);Using Builder Approach in case you need to mix both Dynamic & Lambda Expression
row.Id)
// or .WithOutputId("Id")
.ToTable(dbct.GetTableName(typeof(Row)))
// or .ToTable("Rows")
.Execute(rows);">
new BulkInsertBuilder<Row>(dbct.GetSqlConnection()) .WithColumns(row => new { row.Column1, row.Column2, row.Column3 }) // or .WithColumns([ "Column1", "Column2", "Column3" ]) .WithOutputId(row => row.Id) // or .WithOutputId("Id") .ToTable(dbct.GetTableName(typeof(Row))) // or .ToTable("Rows") .Execute(rows);
SqlConnectionExtensions
Using Lambda Expression
new { row.Column1, row.Column2, row.Column3 });
connection.BulkInsert(compositeKeyRows,
row => new { row.Id1, row.Id2, row.Column1, row.Column2, row.Column3 });
connection.BulkUpdate(rows,
row => row.Id,
row => new { row.Column3, row.Column2 });
connection.BulkUpdate(compositeKeyRows,
row => new { row.Id1, row.Id2 },
row => new { row.Column3, row.Column2 });
connection.BulkMerge(rows,
row => row.Id,
row => new { row.Column1, row.Column2 },
row => new { row.Column1, row.Column2, row.Column3 });
connection.BulkMerge(compositeKeyRows,
row => new { row.Id1, row.Id2 },
row => new { row.Column1, row.Column2, row.Column3 },
row => new { row.Id1, row.Id2, row.Column1, row.Column2, row.Column3 });
connection.BulkDelete(rows, row => row.Id);
connection.BulkDelete(compositeKeyRows, row => new { row.Id1, row.Id2 });">
using EntityFrameworkCore.SqlServer.SimpleBulks.BulkDelete; using EntityFrameworkCore.SqlServer.SimpleBulks.BulkInsert; using EntityFrameworkCore.SqlServer.SimpleBulks.BulkMerge; using EntityFrameworkCore.SqlServer.SimpleBulks.BulkUpdate; // Register Type - Table Name globaly TableMapper.Register(typeof(Row), "Rows"); TableMapper.Register(typeof(CompositeKeyRow), "CompositeKeyRows"); connection.BulkInsert(rows, row => new { row.Column1, row.Column2, row.Column3 }); connection.BulkInsert(compositeKeyRows, row => new { row.Id1, row.Id2, row.Column1, row.Column2, row.Column3 }); connection.BulkUpdate(rows, row => row.Id, row => new { row.Column3, row.Column2 }); connection.BulkUpdate(compositeKeyRows, row => new { row.Id1, row.Id2 }, row => new { row.Column3, row.Column2 }); connection.BulkMerge(rows, row => row.Id, row => new { row.Column1, row.Column2 }, row => new { row.Column1, row.Column2, row.Column3 }); connection.BulkMerge(compositeKeyRows, row => new { row.Id1, row.Id2 }, row => new { row.Column1, row.Column2, row.Column3 }, row => new { row.Id1, row.Id2, row.Column1, row.Column2, row.Column3 }); connection.BulkDelete(rows, row => row.Id); connection.BulkDelete(compositeKeyRows, row => new { row.Id1, row.Id2 });
Using Dynamic String
using EntityFrameworkCore.SqlServer.SimpleBulks.BulkDelete;
using EntityFrameworkCore.SqlServer.SimpleBulks.BulkInsert;
using EntityFrameworkCore.SqlServer.SimpleBulks.BulkMerge;
using EntityFrameworkCore.SqlServer.SimpleBulks.BulkUpdate;
connection.BulkInsert(rows, "Rows",
[ "Column1", "Column2", "Column3" ]);
connection.BulkInsert(rows.Take(1000), "Rows",
typeof(Row).GetDbColumnNames("Id"));
connection.BulkInsert(compositeKeyRows, "CompositeKeyRows",
[ "Id1", "Id2", "Column1", "Column2", "Column3" ]);
connection.BulkUpdate(rows, "Rows",
"Id",
[ "Column3", "Column2" ]);
connection.BulkUpdate(compositeKeyRows, "CompositeKeyRows",
[ "Id1", "Id2" ],
[ "Column3", "Column2" ]);
connection.BulkMerge(rows, "Rows",
"Id",
[ "Column1", "Column2" ],
[ "Column1", "Column2", "Column3" ]);
connection.BulkMerge(compositeKeyRows, "CompositeKeyRows",
[ "Id1", "Id2" ],
[ "Column1", "Column2", "Column3" ],
[ "Id1", "Id2", "Column1", "Column2", "Column3" ]);
connection.BulkDelete(rows, "Rows", "Id");
connection.BulkDelete(compositeKeyRows, "CompositeKeyRows", [ "Id1", "Id2" ]);Using Builder Approach in case you need to mix both Dynamic & Lambda Expression
row.Id)
// or .WithOutputId("Id")
.ToTable("Rows")
.Execute(rows);">
new BulkInsertBuilder<Row>(connection) .WithColumns(row => new { row.Column1, row.Column2, row.Column3 }) // or .WithColumns([ "Column1", "Column2", "Column3" ]) .WithOutputId(row => row.Id) // or .WithOutputId("Id") .ToTable("Rows") .Execute(rows);
Configuration
BulkInsert
_context.BulkInsert(rows,
row => new { row.Column1, row.Column2, row.Column3 },
options =>
{
options.KeepIdentity = false;
options.BatchSize = 0;
options.Timeout = 30;
options.LogTo = Console.WriteLine;
});BulkUpdate
_context.BulkUpdate(rows,
row => new { row.Column3, row.Column2 },
options =>
{
options.BatchSize = 0;
options.Timeout = 30;
options.LogTo = Console.WriteLine;
});BulkDelete
_context.BulkDelete(rows,
options =>
{
options.BatchSize = 0;
options.Timeout = 30;
options.LogTo = Console.WriteLine;
});BulkMerge
_context.BulkMerge(rows,
row => row.Id,
row => new { row.Column1, row.Column2 },
row => new { row.Column1, row.Column2, row.Column3 },
options =>
{
options.BatchSize = 0;
options.Timeout = 30;
options.WithHoldLock = false;
options.ReturnDbGeneratedId = true;
options.LogTo = Console.WriteLine;
});BulkMatch
var contactsFromDb = _context.BulkMatch(matchedContacts,
x => new { x.CustomerId, x.CountryIsoCode },
options =>
{
options.BatchSize = 0;
options.Timeout = 30;
options.LogTo = Console.WriteLine;
});TempTable
var customerTableName = _context.CreateTempTable(customers,
x => new
{
x.IdNumber,
x.FirstName,
x.LastName,
x.CurrentCountryIsoCode
},
options =>
{
options.BatchSize = 0;
options.Timeout = 30;
options.LogTo = Console.WriteLine;
});DirectInsert
_context.DirectInsert(row,
row => new { row.Column1, row.Column2, row.Column3 },
options =>
{
options.Timeout = 30;
options.LogTo = Console.WriteLine;
});DirectUpdate
_context.DirectUpdate(row,
row => new { row.Column3, row.Column2 },
options =>
{
options.Timeout = 30;
options.LogTo = Console.WriteLine;
});DirectDelete
_context.DirectDelete(row,
options =>
{
options.Timeout = 30;
options.LogTo = Console.WriteLine;
});Returned Result
BulkUpdate
var updateResult = dbct.BulkUpdate(rows, row => new { row.Column3, row.Column2 });
Console.WriteLine($"Updated: {updateResult.AffectedRows} row(s)");BulkDelete
var deleteResult = dbct.BulkDelete(rows);
Console.WriteLine($"Deleted: {deleteResult.AffectedRows} row(s)");BulkMerge
var mergeResult = dbct.BulkMerge(rows,
row => row.Id,
row => new { row.Column1, row.Column2 },
row => new { row.Column1, row.Column2, row.Column3 });
Console.WriteLine($"Updated: {mergeResult.UpdatedRows} row(s)");
Console.WriteLine($"Inserted: {mergeResult.InsertedRows} row(s)"
下载源码
通过命令行克隆项目:
git clone https://github.com/phongnguyend/EntityFrameworkCore.SqlServer.SimpleBulks.git