Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/phongnguyend/EntityFrameworkCore.SqlServer.SimpleBulks

Very simple .net library that supports bulk insert (retain client populated Ids or return db generated Ids), bulk update, bulk delete and bulk merge operations. Lambda Expression is supported.
https://github.com/phongnguyend/EntityFrameworkCore.SqlServer.SimpleBulks

bulkdelete bulkinsert bulkmerge bulkupdate efcore entityframeworkcore net netcore

Last synced: about 1 month ago
JSON representation

Very simple .net library that supports bulk insert (retain client populated Ids or return db generated Ids), bulk update, bulk delete and bulk merge operations. Lambda Expression is supported.

Awesome Lists containing this project

README

        

# 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
https://www.nuget.org/packages/EntityFrameworkCore.SqlServer.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](/src/EntityFrameworkCore.SqlServer.SimpleBulks.Demo/Program.cs)
- Update the connection string:
```c#
private const string _connectionString = "Server=.;Database=SimpleBulks;User Id=xxx;Password=xxx";
```
- Build and run.

## DbContextExtensions
### Using Lambda Expression
```c#
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
```c#
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
```c#
new BulkInsertBuilder(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
```c#
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
```c#
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
```c#
new BulkInsertBuilder(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
```c#
_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
```c#
_context.BulkUpdate(rows,
row => new { row.Column3, row.Column2 },
options =>
{
options.BatchSize = 0;
options.Timeout = 30;
options.LogTo = Console.WriteLine;
});
```
### BulkDelete
```c#
_context.BulkDelete(rows,
options =>
{
options.BatchSize = 0;
options.Timeout = 30;
options.LogTo = Console.WriteLine;
});
```
### BulkMerge
```c#
_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
```c#
var contactsFromDb = _context.BulkMatch(matchedContacts,
x => new { x.CustomerId, x.CountryIsoCode },
options =>
{
options.BatchSize = 0;
options.Timeout = 30;
options.LogTo = Console.WriteLine;
});
```
### TempTable
```c#
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
```c#
_context.DirectInsert(row,
row => new { row.Column1, row.Column2, row.Column3 },
options =>
{
options.Timeout = 30;
options.LogTo = Console.WriteLine;
});
```
### DirectUpdate
```c#
_context.DirectUpdate(row,
row => new { row.Column3, row.Column2 },
options =>
{
options.Timeout = 30;
options.LogTo = Console.WriteLine;
});
```
### DirectDelete
```c#
_context.DirectDelete(row,
options =>
{
options.Timeout = 30;
options.LogTo = Console.WriteLine;
});
```

## Returned Result
### BulkUpdate
```c#
var updateResult = dbct.BulkUpdate(rows, row => new { row.Column3, row.Column2 });

Console.WriteLine($"Updated: {updateResult.AffectedRows} row(s)");
```
### BulkDelete
```c#
var deleteResult = dbct.BulkDelete(rows);

Console.WriteLine($"Deleted: {deleteResult.AffectedRows} row(s)");
```
### BulkMerge
```c#
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)");
Console.WriteLine($"Affected: {mergeResult.AffectedRows} row(s)");
```

## Benchmarks
### BulkInsert
Single Table [/src/EntityFrameworkCore.SqlServer.SimpleBulks.Benchmarks/BulkInsertSingleTableBenchmarks.cs](/src/EntityFrameworkCore.SqlServer.SimpleBulks.Benchmarks/BulkInsertSingleTableBenchmarks.cs)

``` ini

BenchmarkDotNet=v0.13.2, OS=Windows 10 (10.0.19045.5011)
11th Gen Intel Core i7-1165G7 2.80GHz, 1 CPU, 8 logical and 4 physical cores
.NET SDK=8.0.400
[Host] : .NET 8.0.8 (8.0.824.36612), X64 RyuJIT AVX2
Job-LGAVYD : .NET 8.0.8 (8.0.824.36612), X64 RyuJIT AVX2

InvocationCount=1 IterationCount=1 UnrollFactor=1
WarmupCount=0

```
| Method | RowsCount | Mean | Error | Gen0 | Gen1 | Gen2 | Allocated |
|------------- |---------- |-------------:|------:|------------:|------------:|----------:|--------------:|
| **EFCoreInsert** | **100** | **45.19 ms** | **NA** | **-** | **-** | **-** | **985.52 KB** |
| BulkInsert | 100 | 32.68 ms | NA | - | - | - | 93.78 KB |
| **EFCoreInsert** | **1000** | **145.41 ms** | **NA** | **1000.0000** | **-** | **-** | **9702.7 KB** |
| BulkInsert | 1000 | 44.94 ms | NA | - | - | - | 573.84 KB |
| **EFCoreInsert** | **10000** | **788.90 ms** | **NA** | **14000.0000** | **5000.0000** | **-** | **95727.38 KB** |
| BulkInsert | 10000 | 126.36 ms | NA | - | - | - | 5320.53 KB |
| **EFCoreInsert** | **100000** | **7,107.29 ms** | **NA** | **146000.0000** | **36000.0000** | **-** | **950162.56 KB** |
| BulkInsert | 100000 | 998.42 ms | NA | 7000.0000 | 3000.0000 | 1000.0000 | 51730.81 KB |
| **EFCoreInsert** | **250000** | **18,542.56 ms** | **NA** | **365000.0000** | **87000.0000** | **-** | **2352262.34 KB** |
| BulkInsert | 250000 | 2,576.88 ms | NA | 16000.0000 | 5000.0000 | 1000.0000 | 125832.63 KB |
| **EFCoreInsert** | **500000** | **34,957.34 ms** | **NA** | **730000.0000** | **170000.0000** | **-** | **4711772.88 KB** |
| BulkInsert | 500000 | 5,553.61 ms | NA | 30000.0000 | 9000.0000 | 1000.0000 | 252707.77 KB |

Multiple Tables (1x parent rows + 5x child rows) [/src/EntityFrameworkCore.SqlServer.SimpleBulks.Benchmarks/BulkInsertMultipleTablesBenchmarks.cs](/src/EntityFrameworkCore.SqlServer.SimpleBulks.Benchmarks/BulkInsertMultipleTablesBenchmarks.cs)

``` ini

BenchmarkDotNet=v0.13.2, OS=Windows 10 (10.0.19045.5011)
11th Gen Intel Core i7-1165G7 2.80GHz, 1 CPU, 8 logical and 4 physical cores
.NET SDK=8.0.400
[Host] : .NET 8.0.8 (8.0.824.36612), X64 RyuJIT AVX2
Job-LGAVYD : .NET 8.0.8 (8.0.824.36612), X64 RyuJIT AVX2

InvocationCount=1 IterationCount=1 UnrollFactor=1
WarmupCount=0

```
| Method | RowsCount | Mean | Error | Gen0 | Gen1 | Gen2 | Allocated |
|------------- |---------- |-------------:|------:|-------------:|------------:|----------:|--------------:|
| **EFCoreInsert** | **100** | **226.22 ms** | **NA** | **1000.0000** | **-** | **-** | **7438.51 KB** |
| BulkInsert | 100 | 48.38 ms | NA | - | - | - | 444.18 KB |
| **EFCoreInsert** | **1000** | **566.95 ms** | **NA** | **11000.0000** | **4000.0000** | **-** | **73518.48 KB** |
| BulkInsert | 1000 | 125.77 ms | NA | - | - | - | 3460.21 KB |
| **EFCoreInsert** | **10000** | **6,268.42 ms** | **NA** | **114000.0000** | **30000.0000** | **-** | **731076.92 KB** |
| BulkInsert | 10000 | 1,066.74 ms | NA | 5000.0000 | 2000.0000 | 1000.0000 | 33324.16 KB |
| **EFCoreInsert** | **100000** | **59,389.89 ms** | **NA** | **1138000.0000** | **264000.0000** | **-** | **7282561.93 KB** |
| BulkInsert | 100000 | 9,504.12 ms | NA | 39000.0000 | 13000.0000 | 1000.0000 | 327100.08 KB |

### BulkUpdate
[/src/EntityFrameworkCore.SqlServer.SimpleBulks.Benchmarks/BulkUpdateBenchmarks.cs](/src/EntityFrameworkCore.SqlServer.SimpleBulks.Benchmarks/BulkUpdateBenchmarks.cs)

``` ini

BenchmarkDotNet=v0.13.2, OS=Windows 10 (10.0.19045.5011)
11th Gen Intel Core i7-1165G7 2.80GHz, 1 CPU, 8 logical and 4 physical cores
.NET SDK=8.0.400
[Host] : .NET 8.0.8 (8.0.824.36612), X64 RyuJIT AVX2
Job-LGAVYD : .NET 8.0.8 (8.0.824.36612), X64 RyuJIT AVX2

InvocationCount=1 IterationCount=1 UnrollFactor=1
WarmupCount=0

```
| Method | RowsCount | Mean | Error | Gen0 | Gen1 | Allocated |
|------------- |---------- |-------------:|------:|------------:|-----------:|--------------:|
| **EFCoreUpdate** | **100** | **61.65 ms** | **NA** | **-** | **-** | **853.66 KB** |
| BulkUpdate | 100 | 27.33 ms | NA | - | - | 63.55 KB |
| **EFCoreUpdate** | **1000** | **143.39 ms** | **NA** | **1000.0000** | **-** | **8398.1 KB** |
| BulkUpdate | 1000 | 43.95 ms | NA | - | - | 379.25 KB |
| **EFCoreUpdate** | **10000** | **685.97 ms** | **NA** | **12000.0000** | **3000.0000** | **82396.19 KB** |
| BulkUpdate | 10000 | 182.54 ms | NA | - | - | 3499.74 KB |
| **EFCoreUpdate** | **100000** | **8,495.18 ms** | **NA** | **120000.0000** | **28000.0000** | **810248.07 KB** |
| BulkUpdate | 100000 | 2,091.42 ms | NA | 5000.0000 | 1000.0000 | 33819.46 KB |
| **EFCoreUpdate** | **250000** | **17,859.49 ms** | **NA** | **300000.0000** | **69000.0000** | **2005895.77 KB** |
| BulkUpdate | 250000 | 4,290.07 ms | NA | 13000.0000 | 7000.0000 | 84352 KB |

``` ini

BenchmarkDotNet=v0.13.2, OS=Windows 10 (10.0.19045.5011)
11th Gen Intel Core i7-1165G7 2.80GHz, 1 CPU, 8 logical and 4 physical cores
.NET SDK=8.0.400
[Host] : .NET 8.0.8 (8.0.824.36612), X64 RyuJIT AVX2
Job-LGAVYD : .NET 8.0.8 (8.0.824.36612), X64 RyuJIT AVX2

InvocationCount=1 IterationCount=1 UnrollFactor=1
WarmupCount=0

```
| Method | RowsCount | Mean | Error | Gen0 | Gen1 | Allocated |
|----------- |---------- |--------:|------:|-----------:|-----------:|----------:|
| **BulkUpdate** | **500000** | **10.19 s** | **NA** | **27000.0000** | **16000.0000** | **164.63 MB** |
| **BulkUpdate** | **1000000** | **17.03 s** | **NA** | **54000.0000** | **37000.0000** | **329.12 MB** |

### BulkDelete
[/src/EntityFrameworkCore.SqlServer.SimpleBulks.Benchmarks/BulkDeleteBenchmarks.cs](/src/EntityFrameworkCore.SqlServer.SimpleBulks.Benchmarks/BulkDeleteBenchmarks.cs)

``` ini

BenchmarkDotNet=v0.13.2, OS=Windows 10 (10.0.19045.5011)
11th Gen Intel Core i7-1165G7 2.80GHz, 1 CPU, 8 logical and 4 physical cores
.NET SDK=8.0.400
[Host] : .NET 8.0.8 (8.0.824.36612), X64 RyuJIT AVX2
Job-LGAVYD : .NET 8.0.8 (8.0.824.36612), X64 RyuJIT AVX2

InvocationCount=1 IterationCount=1 UnrollFactor=1
WarmupCount=0

```
| Method | RowsCount | Mean | Error | Gen0 | Gen1 | Allocated |
|------------- |---------- |-------------:|------:|-----------:|-----------:|-------------:|
| **EFCoreDelete** | **100** | **73.25 ms** | **NA** | **-** | **-** | **681.09 KB** |
| BulkDelete | 100 | 29.42 ms | NA | - | - | 43.45 KB |
| **EFCoreDelete** | **1000** | **176.83 ms** | **NA** | **1000.0000** | **1000.0000** | **6745 KB** |
| BulkDelete | 1000 | 27.19 ms | NA | - | - | 236.86 KB |
| **EFCoreDelete** | **10000** | **1,489.03 ms** | **NA** | **10000.0000** | **2000.0000** | **66031.55 KB** |
| BulkDelete | 10000 | 431.74 ms | NA | - | - | 2150.99 KB |
| **EFCoreDelete** | **20000** | **6,084.87 ms** | **NA** | **20000.0000** | **7000.0000** | **132403.3 KB** |
| BulkDelete | 20000 | 276.52 ms | NA | - | - | 4276.01 KB |
| **EFCoreDelete** | **50000** | **39,933.60 ms** | **NA** | **49000.0000** | **14000.0000** | **326164.25 KB** |
| BulkDelete | 50000 | 1,477.09 ms | NA | 1000.0000 | - | 10594.63 KB |

``` ini

BenchmarkDotNet=v0.13.2, OS=Windows 10 (10.0.19045.5011)
11th Gen Intel Core i7-1165G7 2.80GHz, 1 CPU, 8 logical and 4 physical cores
.NET SDK=8.0.400
[Host] : .NET 8.0.8 (8.0.824.36612), X64 RyuJIT AVX2
Job-LGAVYD : .NET 8.0.8 (8.0.824.36612), X64 RyuJIT AVX2

InvocationCount=1 IterationCount=1 UnrollFactor=1
WarmupCount=0

```
| Method | RowsCount | Mean | Error | Gen0 | Gen1 | Allocated |
|----------- |---------- |-----------:|------:|-----------:|-----------:|----------:|
| **BulkDelete** | **100000** | **937.7 ms** | **NA** | **3000.0000** | **1000.0000** | **20.67 MB** |
| **BulkDelete** | **250000** | **2,619.7 ms** | **NA** | **7000.0000** | **3000.0000** | **51.7 MB** |
| **BulkDelete** | **500000** | **4,897.7 ms** | **NA** | **13000.0000** | **6000.0000** | **103.22 MB** |
| **BulkDelete** | **1000000** | **9,466.0 ms** | **NA** | **26000.0000** | **12000.0000** | **206.28 MB** |

### BulkMerge
[/src/EntityFrameworkCore.SqlServer.SimpleBulks.Benchmarks/BulkMergeBenchmarks.cs](/src/EntityFrameworkCore.SqlServer.SimpleBulks.Benchmarks/BulkMergeBenchmarks.cs)

``` ini

BenchmarkDotNet=v0.13.2, OS=Windows 10 (10.0.19045.5011)
11th Gen Intel Core i7-1165G7 2.80GHz, 1 CPU, 8 logical and 4 physical cores
.NET SDK=8.0.400
[Host] : .NET 8.0.8 (8.0.824.36612), X64 RyuJIT AVX2
Job-LGAVYD : .NET 8.0.8 (8.0.824.36612), X64 RyuJIT AVX2

InvocationCount=1 IterationCount=1 UnrollFactor=1
WarmupCount=0

```
| Method | RowsCount | Mean | Error | Gen0 | Gen1 | Gen2 | Allocated |
|------------- |---------- |-------------:|------:|------------:|------------:|----------:|--------------:|
| **EFCoreUpsert** | **100** | **82.11 ms** | **NA** | **-** | **-** | **-** | **1840.23 KB** |
| BulkMerge | 100 | 34.27 ms | NA | - | - | - | 162.96 KB |
| **EFCoreUpsert** | **1000** | **266.86 ms** | **NA** | **2000.0000** | **1000.0000** | **-** | **17984.91 KB** |
| BulkMerge | 1000 | 79.45 ms | NA | - | - | - | 1213.33 KB |
| **EFCoreUpsert** | **10000** | **1,451.20 ms** | **NA** | **26000.0000** | **8000.0000** | **-** | **178385.15 KB** |
| BulkMerge | 10000 | 677.47 ms | NA | 1000.0000 | - | - | 11679.42 KB |
| **EFCoreUpsert** | **100000** | **13,902.06 ms** | **NA** | **266000.0000** | **63000.0000** | **-** | **1762696.52 KB** |
| BulkMerge | 100000 | 3,415.31 ms | NA | 16000.0000 | 6000.0000 | 1000.0000 | 115233.2 KB |
| **EFCoreUpsert** | **250000** | **36,167.51 ms** | **NA** | **665000.0000** | **152000.0000** | **-** | **4362872.57 KB** |
| BulkMerge | 250000 | 7,681.71 ms | NA | 37000.0000 | 11000.0000 | 1000.0000 | 284187.09 KB |

[/src/EntityFrameworkCore.SqlServer.SimpleBulks.Benchmarks/BulkMergeReturnDbGeneratedIdBenchmarks.cs](/src/EntityFrameworkCore.SqlServer.SimpleBulks.Benchmarks/BulkMergeReturnDbGeneratedIdBenchmarks.cs)

``` ini

BenchmarkDotNet=v0.13.2, OS=Windows 10 (10.0.19045.5011)
11th Gen Intel Core i7-1165G7 2.80GHz, 1 CPU, 8 logical and 4 physical cores
.NET SDK=8.0.400
[Host] : .NET 8.0.8 (8.0.824.36612), X64 RyuJIT AVX2
Job-LGAVYD : .NET 8.0.8 (8.0.824.36612), X64 RyuJIT AVX2

InvocationCount=1 IterationCount=1 UnrollFactor=1
WarmupCount=0

```
| Method | RowsCount | Mean | Error | Gen0 | Gen1 | Gen2 | Allocated |
|----------------------- |---------- |------------:|------:|-----------:|----------:|----------:|-------------:|
| **ReturnDbGeneratedId** | **100** | **38.45 ms** | **NA** | **-** | **-** | **-** | **151.09 KB** |
| NotReturnDbGeneratedId | 100 | 37.75 ms | NA | - | - | - | 116.8 KB |
| **ReturnDbGeneratedId** | **1000** | **67.42 ms** | **NA** | **-** | **-** | **-** | **1099.48 KB** |
| NotReturnDbGeneratedId | 1000 | 60.02 ms | NA | - | - | - | 769.23 KB |
| **ReturnDbGeneratedId** | **10000** | **783.73 ms** | **NA** | **1000.0000** | **-** | **-** | **10543.62 KB** |
| NotReturnDbGeneratedId | 10000 | 501.07 ms | NA | 1000.0000 | - | - | 7348.79 KB |
| **ReturnDbGeneratedId** | **100000** | **3,187.89 ms** | **NA** | **14000.0000** | **5000.0000** | **1000.0000** | **103878.09 KB** |
| NotReturnDbGeneratedId | 100000 | 2,741.31 ms | NA | 11000.0000 | 5000.0000 | 1000.0000 | 72936.01 KB |

``` ini

BenchmarkDotNet=v0.13.2, OS=Windows 10 (10.0.19045.5011)
11th Gen Intel Core i7-1165G7 2.80GHz, 1 CPU, 8 logical and 4 physical cores
.NET SDK=8.0.400
[Host] : .NET 8.0.8 (8.0.824.36612), X64 RyuJIT AVX2
Job-LGAVYD : .NET 8.0.8 (8.0.824.36612), X64 RyuJIT AVX2

InvocationCount=1 IterationCount=1 UnrollFactor=1
WarmupCount=0

```
| Method | RowsCount | Mean | Error | Gen0 | Gen1 | Gen2 | Allocated |
|----------------------- |---------- |---------:|------:|------------:|-----------:|----------:|-----------:|
| **ReturnDbGeneratedId** | **250000** | **7.799 s** | **NA** | **32000.0000** | **8000.0000** | **-** | **249.8 MB** |
| NotReturnDbGeneratedId | 250000 | 6.619 s | NA | 24000.0000 | 7000.0000 | - | 177.7 MB |
| **ReturnDbGeneratedId** | **500000** | **15.051 s** | **NA** | **66000.0000** | **19000.0000** | **1000.0000** | **500.64 MB** |
| NotReturnDbGeneratedId | 500000 | 14.328 s | NA | 47000.0000 | 14000.0000 | - | 355.19 MB |
| **ReturnDbGeneratedId** | **1000000** | **32.449 s** | **NA** | **129000.0000** | **34000.0000** | **-** | **1003.67 MB** |
| NotReturnDbGeneratedId | 1000000 | 28.253 s | NA | 95000.0000 | 28000.0000 | - | 710.22 MB |

### BulkMatch
Single Column [/src/EntityFrameworkCore.SqlServer.SimpleBulks.Benchmarks/BulkMatchSingleColumnBenchmarks.cs](/src/EntityFrameworkCore.SqlServer.SimpleBulks.Benchmarks/BulkMatchSingleColumnBenchmarks.cs)

``` ini

BenchmarkDotNet=v0.13.2, OS=Windows 10 (10.0.19045.5011)
11th Gen Intel Core i7-1165G7 2.80GHz, 1 CPU, 8 logical and 4 physical cores
.NET SDK=8.0.400
[Host] : .NET 8.0.8 (8.0.824.36612), X64 RyuJIT AVX2
Job-LGAVYD : .NET 8.0.8 (8.0.824.36612), X64 RyuJIT AVX2

InvocationCount=1 IterationCount=1 UnrollFactor=1
WarmupCount=0

```
| Method | RowsCount | Mean | Error | Gen0 | Gen1 | Gen2 | Allocated |
|------------------ |---------- |--------------:|------:|------------:|-----------:|----------:|------------:|
| **EFCoreSelect** | **100** | **97.373 ms** | **NA** | **-** | **-** | **-** | **1008.33 KB** |
| EFCoreBatchSelect | 100 | 7.166 ms | NA | - | - | - | 94.77 KB |
| BulkMatch | 100 | 8.570 ms | NA | - | - | - | 106.63 KB |
| **EFCoreSelect** | **1000** | **720.250 ms** | **NA** | **1000.0000** | **-** | **-** | **9761.42 KB** |
| EFCoreBatchSelect | 1000 | 6.375 ms | NA | - | - | - | 908.18 KB |
| BulkMatch | 1000 | 15.445 ms | NA | - | - | - | 820.36 KB |
| **EFCoreSelect** | **10000** | **8,075.686 ms** | **NA** | **15000.0000** | **1000.0000** | **-** | **97115.62 KB** |
| EFCoreBatchSelect | 10000 | 66.438 ms | NA | 1000.0000 | - | - | 9092.91 KB |
| BulkMatch | 10000 | 69.430 ms | NA | 1000.0000 | - | - | 8177.76 KB |
| **EFCoreSelect** | **100000** | **81,088.718 ms** | **NA** | **159000.0000** | **31000.0000** | **1000.0000** | **972204.7 KB** |
| EFCoreBatchSelect | 100000 | 920.412 ms | NA | 11000.0000 | 4000.0000 | 1000.0000 | 91808.56 KB |
| BulkMatch | 100000 | 742.030 ms | NA | 13000.0000 | 6000.0000 | 1000.0000 | 82419.43 KB |

``` ini

BenchmarkDotNet=v0.13.2, OS=Windows 10 (10.0.19045.5011)
11th Gen Intel Core i7-1165G7 2.80GHz, 1 CPU, 8 logical and 4 physical cores
.NET SDK=8.0.400
[Host] : .NET 8.0.8 (8.0.824.36612), X64 RyuJIT AVX2
Job-LGAVYD : .NET 8.0.8 (8.0.824.36612), X64 RyuJIT AVX2

InvocationCount=1 IterationCount=1 UnrollFactor=1
WarmupCount=0

```
| Method | RowsCount | Mean | Error | Gen0 | Gen1 | Gen2 | Allocated |
|------------------ |---------- |---------:|------:|------------:|-----------:|----------:|----------:|
| **EFCoreBatchSelect** | **250000** | **2.101 s** | **NA** | **26000.0000** | **11000.0000** | **1000.0000** | **224.05 MB** |
| BulkMatch | 250000 | 2.067 s | NA | 32000.0000 | 12000.0000 | 1000.0000 | 201.64 MB |
| **EFCoreBatchSelect** | **500000** | **4.239 s** | **NA** | **53000.0000** | **20000.0000** | **2000.0000** | **448.85 MB** |
| BulkMatch | 500000 | 4.507 s | NA | 62000.0000 | 24000.0000 | 1000.0000 | 404.03 MB |
| **EFCoreBatchSelect** | **1000000** | **8.523 s** | **NA** | **103000.0000** | **38000.0000** | **1000.0000** | **898.44 MB** |
| BulkMatch | 1000000 | 11.585 s | NA | 123000.0000 | 46000.0000 | 1000.0000 | 808.82 MB |

Multiple Columns [/src/EntityFrameworkCore.SqlServer.SimpleBulks.Benchmarks/BulkMatchMultipleColumnsBenchmarks.cs](/src/EntityFrameworkCore.SqlServer.SimpleBulks.Benchmarks/BulkMatchMultipleColumnsBenchmarks.cs)

``` ini

BenchmarkDotNet=v0.13.2, OS=Windows 10 (10.0.19045.5011)
11th Gen Intel Core i7-1165G7 2.80GHz, 1 CPU, 8 logical and 4 physical cores
.NET SDK=8.0.400
[Host] : .NET 8.0.8 (8.0.824.36612), X64 RyuJIT AVX2
Job-LGAVYD : .NET 8.0.8 (8.0.824.36612), X64 RyuJIT AVX2

InvocationCount=1 IterationCount=1 UnrollFactor=1
WarmupCount=0

```
| Method | RowsCount | Mean | Error | Gen0 | Gen1 | Allocated |
|------------- |---------- |-------------:|------:|------------:|-----------:|--------------:|
| **EFCoreSelect** | **100** | **130.11 ms** | **NA** | **-** | **-** | **1256.8 KB** |
| BulkMatch | 100 | 15.46 ms | NA | - | - | 173.56 KB |
| **EFCoreSelect** | **1000** | **997.87 ms** | **NA** | **2000.0000** | **-** | **12373.85 KB** |
| BulkMatch | 1000 | 43.35 ms | NA | - | - | 1358.77 KB |
| **EFCoreSelect** | **10000** | **9,769.96 ms** | **NA** | **20000.0000** | **4000.0000** | **123595.97 KB** |
| BulkMatch | 10000 | 238.80 ms | NA | 2000.0000 | 1000.0000 | 13768.49 KB |
| **EFCoreSelect** | **100000** | **89,204.16 ms** | **NA** | **201000.0000** | **51000.0000** | **1237424.23 KB** |
| BulkMatch | 100000 | 2,612.00 ms | NA | 21000.0000 | 8000.0000 | 138686.52 KB |

``` ini

BenchmarkDotNet=v0.13.2, OS=Windows 10 (10.0.19045.5011)
11th Gen Intel Core i7-1165G7 2.80GHz, 1 CPU, 8 logical and 4 physical cores
.NET SDK=8.0.400
[Host] : .NET 8.0.8 (8.0.824.36612), X64 RyuJIT AVX2
Job-LGAVYD : .NET 8.0.8 (8.0.824.36612), X64 RyuJIT AVX2

InvocationCount=1 IterationCount=1 UnrollFactor=1
WarmupCount=0

```
| Method | RowsCount | Mean | Error | Gen0 | Gen1 | Allocated |
|---------- |---------- |---------:|------:|------------:|-----------:|-----------:|
| **BulkMatch** | **250000** | **6.709 s** | **NA** | **53000.0000** | **19000.0000** | **340.68 MB** |
| **BulkMatch** | **500000** | **12.939 s** | **NA** | **107000.0000** | **36000.0000** | **683.46 MB** |
| **BulkMatch** | **1000000** | **25.418 s** | **NA** | **214000.0000** | **74000.0000** | **1369.34 MB** |

### TempTable
[/src/EntityFrameworkCore.SqlServer.SimpleBulks.Benchmarks/TempTableBenchmarks.cs](/src/EntityFrameworkCore.SqlServer.SimpleBulks.Benchmarks/TempTableBenchmarks.cs)

``` ini

BenchmarkDotNet=v0.13.2, OS=Windows 10 (10.0.19045.5011)
11th Gen Intel Core i7-1165G7 2.80GHz, 1 CPU, 8 logical and 4 physical cores
.NET SDK=8.0.400
[Host] : .NET 8.0.8 (8.0.824.36612), X64 RyuJIT AVX2
Job-LGAVYD : .NET 8.0.8 (8.0.824.36612), X64 RyuJIT AVX2

InvocationCount=1 IterationCount=1 UnrollFactor=1
WarmupCount=0

```
| Method | RowsCount | Mean | Error | Gen0 | Gen1 | Gen2 | Allocated |
|---------------- |---------- |-------------:|------:|-----------:|-----------:|----------:|-------------:|
| **CreateTempTable** | **100** | **7.639 ms** | **NA** | **-** | **-** | **-** | **68.03 KB** |
| **CreateTempTable** | **1000** | **14.077 ms** | **NA** | **-** | **-** | **-** | **373.76 KB** |
| **CreateTempTable** | **10000** | **89.789 ms** | **NA** | **-** | **-** | **-** | **3455.46 KB** |
| **CreateTempTable** | **100000** | **574.937 ms** | **NA** | **4000.0000** | **1000.0000** | **-** | **34081.95 KB** |
| **CreateTempTable** | **250000** | **1,403.071 ms** | **NA** | **12000.0000** | **5000.0000** | **1000.0000** | **85229.91 KB** |
| **CreateTempTable** | **500000** | **2,838.562 ms** | **NA** | **22000.0000** | **8000.0000** | **1000.0000** | **170241.85 KB** |
| **CreateTempTable** | **1000000** | **6,198.206 ms** | **NA** | **43000.0000** | **14000.0000** | **1000.0000** | **340282.7 KB** |

## License
**EntityFrameworkCore.SqlServer.SimpleBulks** is licensed under the [MIT](/LICENSE) license.