Interception in Entity Framework Core

Right now, Entity Framework Core still does not have all of the features provided by pre-Core versions, I even wrote a post about this. One of this features is the ability to intercept queries, something that was provided by the IDbCommandInterceptor, IDbCommandTreeInterceptor interfaces.

What we have in EF Core 2.0 is interception at the SQL level, and we can only get to this in a rather convoluted way, through the DiagnosticSource mechanism (yes, I do intend to write about it!). So, let’s create a class with two methods, like this:

public class CommandListener
{
[DiagnosticName("Microsoft.EntityFrameworkCore.Database.Command.CommandExecuting")]
public void OnCommandExecuting(DbCommand command, DbCommandMethod executeMethod, Guid commandId, Guid connectionId, bool async, DateTimeOffset startTime)
{
}

[DiagnosticName("Microsoft.EntityFrameworkCore.Database.Command.CommandExecuted")]
public void OnCommandExecuted(object result, bool async)
{
}
}
You will need the Microsoft.Extensions.DiagnosticAdapter NuGet package to compile this.
We hook these methods to EF Core like this:
var listener = ctx.GetService<DiagnosticSource>();
(listener as DiagnosticListener).SubscribeWithAdapter(new CommandListener());
Here, ctx is a DbContext, and we are accessing it’s registered DiagnosticSource service, which is actually a DiagnosticListener, just not registered as such. We just need to add a subscriber, and that’s all!
From the OnCommandExecuted method – by the way, you can call these methods whatever you like, as long as you keep the [DiagnosticName] attributes –, the result parameter will contain either a scalar (in the case of a ExecuteScalar/ExecuteScalarAsync call), a number (for ExecuteNonQuery/ExecuteNonQueryAsync) or a RelationalDataReader object (in the case of a ExecuteReader/ExecuteReaderAsync call). async, of course, will tell you exactly what version of the method was executed.
OnCommandExecuting is more interesting, because here we actually get access to the DbCommand that is about to execute the SQL command, and we can therefore modify its SQL or parameters.
There are other interception mechanisms, such as IQuerySqlGenerator and IQueryCompiler, and I will probably cover them in a future post. For now, hope this helps! Winking smile



                             

1 Comment

  • Good info about Interception in Entity Framework Core.

Add a Comment

As it will appear on the website

Not displayed

Your website