Entity Framework Additional Features
We have seen in the previous getting started article that Entity Framework Extensions (EF Extensions) extends EF Core and EF6 with bulk operations.
Bulk operations are usually the first reason people start using EF Extensions.
However, as you use Entity Framework more, you quickly discover that many scenarios require different ways to read, save, or process data, depending on your needs.
That’s where the additional features of EF Extensions come in.
In this section, we will explore the following features that help you work more efficiently, handle advanced scenarios, and keep your code simple and fast:
- BulkSaveChanges Method
- BatchSaveChanges Method
- Batch Operations Methods
- InsertFromQuery
- UpdateFromQuery
- DeleteFromQuery
- Where Methods
- BulkRead
- WhereBulkContains
- WhereNotBulkContains
- WhereBulkContainsFilterList
- WhereBulkNotContainsFilterList
BulkSaveChanges Method
EF Extensions allows you to improve performance in EF Core and EF6 by replacing the SaveChanges method with the BulkSaveChanges method.
As the name indicates, BulkSaveChanges saves data more efficiently by using bulk operations under the hood.
To use this method, you simply need to call BulkSaveChanges instead of SaveChanges:
// @nuget: Z.EntityFramework.Extensions.EFCore using Z.EntityFramework.Extensions; // Easy to use context.BulkSaveChanges(); // Easy to customize context.BulkSaveChanges(options => options.BatchSize = 100);
Learn more about BulkSaveChanges.
BatchSaveChanges Method
The BatchSaveChanges method is only available for EF6.
This method allows you to batch multiple save commands into fewer database commands, which increases the overall saving performance.
In fact, the performance improvement was so significant that EF Core later adopted a similar approach for multiple providers such as PostgreSQL, MySQL, and MariaDB.
To use this method, you simply need to call BatchSaveChanges instead of SaveChanges:
// @nuget: Z.EntityFramework.Extensions.EFCore using Z.EntityFramework.Extensions; var affectedRows = context.BatchSaveChanges();
The performance improvement is often around 500% faster:
| Operations | 50 Entities | 200 Entities | 500 Entities |
|---|---|---|---|
| SaveChanges | 65 ms | 250 ms | 600 ms |
| BatchSaveChanges | 25 ms | 50 ms | 125 ms |
BatchSaveChanges provides the best performance when you have a few hundreds of entities to save, but it does not scale as well as BulkSaveChanges.
For thousands of entities, BulkSaveChanges is the recommended approach.
Learn more about BatchSaveChanges.
Batch Operations Methods
The batch operations methods, also called “from query” methods, allow you to perform INSERT, UPDATE, or DELETE operations directly in the database by using a LINQ query, without loading entities into the context.
Because these operations are executed directly in SQL, they bypass the Change Tracker and work on sets of rows at once, which makes them extremely fast and memory-efficient.
These methods are ideal for data maintenance, cleanup tasks, status updates, and one-time or recurring operations where loading entities is unnecessary.
There are 3 methods that support both EF Core and EF6:
// @nuget: Z.EntityFramework.Extensions.EFCore using Z.EntityFramework.Extensions; var dateToDeactivate = DateTime.Now.AddYears(-2); // INSERT inactive customers into a backup table context.Customers .Where(x => !x.IsActive && !x.Invoices.Any()) .InsertFromQuery("bck_Customers", x => new { x.CustomerID, x.Code, x.Name, x.Email, x.LastLogin }); // UPDATE active customers who haven’t logged in recently context.Customers .Where(x => x.IsActive && x.LastLogin < dateToDeactivate) .UpdateFromQuery(x => new Customer { IsActive = false }); // DELETE inactive customers context.Customers .Where(x => !x.IsActive && !x.Invoices.Any()) .DeleteFromQuery();
For people using EF Core 7+, you can alternatively use the built-in methods:
- ExecuteUpdate
- ExecuteDelete
- (No built-in method is available to replace
InsertFromQuery)
Where Methods
Where methods are five methods added to both EF Core and EF6 to improve how data is read and filtered.
These methods are designed to solve scenarios where the standard LINQ Where and Contains methods don’t scale well or simply cannot handle complex inputs.
The available methods are:
- BulkRead: Retrieve entities using a filtered query
- WhereBulkContains: Filter the query to include matching items
- WhereNotBulkContains: Filter the query to exclude matching items
- WhereBulkContainsFilterList: Return entities from the list that exist in the database
- WhereBulkNotContainsFilterList: Return entities from the list that don’t exist in the database
// @nuget: Z.EntityFramework.Extensions.EFCore using Z.EntityFramework.Extensions; // --- Retrieval Operations --- context.Customers.BulkRead(deserializedCustomers); // Retrieve entities using a filtered query context.Customers.WhereBulkContains(deserializedCustomers).ToList(); // Include matching items context.Customers.WhereBulkNotContains(deserializedCustomers).ToList(); // Exclude matching items context.Customers.WhereBulkContainsFilterList(deserializedCustomers).ToList(); // Return list items that exist in the database context.Customers.WhereBulkNotContainsFilterList(deserializedCustomers).ToList(); // Return list items that don't exist in the database
These methods are especially useful when working with large lists or external data sources, such as deserialized files, APIs, or in-memory collections.
Their main advantages are:
- Can be used with millions of entities
- Support custom keys and composite keys
- Support all kinds of lists:
- Basic types such as
List<int>andList<Guid> - Entity types such as
List<Customer> - Anonymous types
- Expando object lists
- Basic types such as
All of these scenarios are impossible to handle with the traditional LINQ Where and Contains methods.
The main documentation entry point for these features is the WhereBulkContains method.
Summary & Next Steps
Entity Framework Extensions goes far beyond basic bulk operations.
The additional features covered in this article help you handle advanced scenarios efficiently, without loading unnecessary data or writing raw SQL.
As a rule of thumb:
- Use BulkSaveChanges for an easy performance upgrade with minimal code changes
- Use BatchSaveChanges when working with EF6 and saving a few hundreds of entities
- Use from query methods for maintenance tasks, cleanup jobs, or large set-based operations
- Use Where methods when LINQ
WhereandContainsno longer scale
From here, you can explore the individual documentation pages linked above to see practical examples, advanced options, and best practices.
ZZZ Projects