EF Core Bulk SaveChanges Optimize Entity Framework Saving Performance
Description
The EF BulkSaveChanges
extension method execute bulk operations from entries to save.
// Easy to use context.BulkSaveChanges(); // Easy to customize context.BulkSaveChanges(options => options.BatchSize = 100);
Try it in EF Core | Try it in EF6
Performance Comparison
Operations | 1,000 Entities | 2,000 Entities | 5,000 Entities |
---|---|---|---|
SaveChanges | 1,200 ms | 2,400 ms | 6,000 ms |
BulkSaveChanges | 150 ms | 225 ms | 500 ms |
Try it in EF Core | Try it in EF6
HINT:A lot of factors might affect the benchmark time such as index, column type, latency, throttling, etc.
What is supported?
- All Entity Framework Core Version: EF Core 7, EF Core 6, EF Core 5, EF Core 3
- All Entity Framework Version: EF6, EF5, EF4
- All Inheritances (TPC, TPH, TPT)
- Complex Type/Owned Entity Type
- Enum
- Value Converter (EF Core)
- And more!
Advantages
- Easy to use
- Flexible
- Increase performance
- Increase application responsivness
- Reduce database load
- Reduce database round-trips
FAQ
Why BulkSaveChanges is faster than SaveChanges?
The SaveChanges
method makes it quite slow/impossible to handle a scenario that requires to save a lot of entities due to the number of database round-trips required. The SaveChanges
perform one database round-trip for every entity to insert. So, if you need to insert 10,000 entities, 10,000 database round-trips will be performed which is INSANELY slow.
The BulkSaveChanges
in counterpart requires the minimum number of database round-trips possible. By using Bulk Operations, fewer commands are executed which lead to better performance.
Why BulkSaveChanges update all columns by default (EF6 only)?
The BulkSaveChanges
try to combine most commands in a single operation. Updating different columns from an action to another will require generating different SQL and being executed in several database round-trips.
That's still possible to have the same behavior of SaveChanges
by disabling the option ForceUpdateUnmodifiedValues
:
ctx.BulkSaveChanges(options => options.ForceUpdateUnmodifiedValues = false);
For EF Core
, this option is not available. Only columns that have a modification will be saved exactly like SaveChanges
.
When should I use BulkSaveChanges over SaveChanges?
Whenever you have more than one entity to save. The BulkSaveChanges
is almost as fast as the SaveChanges
for one entity, but becomes way faster as the number of entities to save grows.
When should I use BulkSaveChanges over BatchSaveChanges?
BatchSaveChanges
become slower and slower in comparisons to BulkSaveChanges
when the number of entities to save grows due to the ChangeTracker
.
After a few thousands of entities, we recommend using BulkSaveChanges
which is a more scalable solution.
Documentation
BatchSaveChanges
Methods
Name | Description | Example |
---|---|---|
BulkSaveChanges() |
Save all changes made in this context to the underlying database by executing bulk operations. | EFCore / EF6 |
BulkSaveChanges(Action<BulkOperation> bulkOperationFactory) |
Save all changes made in this context to the underlying database by executing bulk operations. | EFCore / EF6 |
BulkSaveChanges(bool useEntityFrameworkPropagation) |
Save all changes made in this context to the underlying database by executing bulk operations. | EFCore / EF6 |
BulkSaveChanges(bool useEntityFrameworkPropagation, Action<BulkOperation> bulkOperationFactory) |
Save all changes made in this context to the underlying database by executing bulk operations. | EFCore / EF6 |
BulkSaveChangesAsync() |
Save all changes asynchronously made in this context to the underlying database by executing bulk operations. | EFCore / EF6 |
BulkSaveChangesAsync(Action<BulkOperation> bulkOperationFactory) |
Save all changes asynchronously made in this context to the underlying database by executing bulk operations. | EFCore / EF6 |
BulkSaveChangesAsync(bool useEntityFrameworkPropagation) |
Save all changes asynchronously made in this context to the underlying database by executing bulk operations. | EF6 |
BulkSaveChangesAsync(bool useEntityFrameworkPropagation, Action<BulkOperation> bulkOperationFactory) |
Save all changes asynchronously made in this context to the underlying database by executing bulk operations. | EF6 |
Options
More options can be found here:
- Audit
- Batch
- Column
- Context Factory
- Execute Event
- Identity
- Include Graph
- Key
- Logging
- Temporary Table
- Transaction
- Transient Error
- SQL Server
ZZZ Projects