Entity Framework Core (EF Core) is a powerful and flexible object-relational mapping (ORM) framework for .NET applications, enabling developers to work with relational databases using strongly-typed .NET objects. It simplifies data access by abstracting the database interactions, allowing developers to focus more on the application's business logic.
One of the key features of EF Core is its extensibility through the EF Core pipeline. The pipeline represents the sequence of operations that occur when EF Core interacts with the database. Developers can tap into this pipeline to customize or extend the behavior of EF Core to suit their application's specific requirements.
Tapping into the EF Core pipeline allows developers to:
Intercept database operations: By intercepting operations such as query execution, saving changes, or database schema creation, developers can add custom logic, logging, or validation.
Customize query generation: EF Core generates SQL queries based on LINQ expressions or raw SQL statements. Developers can customize this process to optimize queries or handle specific database features.
Implement change tracking: EF Core tracks changes made to entities and detects when to insert, update, or delete records in the database. Developers can customize change tracking behavior for performance or business logic reasons.
There are 3 most common ways to deal with EF Core pipeline:
Override the
SaveChanges
method.Using the saving and tracking event handlers
Interceptors
In the next sections of this article, we will delve into code examples and techniques for tapping into the EF Core pipeline, showcasing the flexibility and power it provides to developers working with database interactions in their .NET applications.
Override the SaveChanges
method
SaveChanges
method saves the changes made to entities to the database. It prepares the SQL queries to insert, update or delete the records. EF Core allows to override this method in DBContext
class.
public override int SaveChanges() {
var result = base.SaveChanges();
return result;
}
Developer could perform various operations in this overridden method. Some examples of such operations are:
adding additional logging before or after saving the changes.
Modifying the entities in change tracker before saving the data. (updating the shadow properties)
Saving and tracking event handlers
EF Core provides below events which could be used to perform operations before, after or during EF Core operations:
Event Name | Description | Example |
SavingChanges | Fired at the beginning of a call to SaveChanges | SavingChanges += DataContext_SavingChanges; |
SavedChanges | Fired at the end of a call to SaveChanges | SavedChanges += DataContext_SavedChanges; |
SaveChangesFailed | Fired when SaveChanges fails with an exception | SaveChangesFailed += DataContext_SaveChangesFailed; |
ChangeTracker.StateChanged | When entity moves from one tracked state to another | ChangeTracker.StateChanged += ChangeTracker_StateChanged; |
ChangeTracker.StateChanging | When entity is moving from one state to another | ChangeTracker.StateChanging += ChangeTracker_StateChanging; |
Using Interceptor to work with EF Core pipeline
Interceptors allows to intercept the EF Core operations; developer could modify or suppress the intercepted operation.
Interceptors are different from logging and diagnostic as they allow modification or suppression of operation.
There are three types of interceptors provided by EF Core:
Interceptor | Database operations intercepted |
IDbCommandInterceptor | Creating commands |
Executing commands | |
Command failures | |
Disposing the command's DbDataReader | |
IDbConnectionInterceptor | Opening and closing connections |
Connection failures | |
IDbTransactionInterceptor | Creating transactions |
Using existing transactions | |
Committing transactions | |
Rolling back transactions | |
Creating and using savepoints | |
Transaction failures |
Table source: Interceptors - EF Core | Microsoft Learn
That's it for now, in this article we have learnt about tapping into EF Core pipeline where developer could perform additional operations before or after execution of operation. Let me know your feedback in comments.