Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Inject debug information into Entity Framework queries

We're using Dapper and EF in our shop, and Dapper proofed to be extremely helpful in debugging queries in SQL server when something went wrong. Instead of just submitting raw SQL, we created a thin decorator that also adds some context information (the origin) as an SQL comment, something like

/* Foo.Bar.GetOrders() */ SELECT * FROM Order WHERE orderId > 123

This allows our DBAs and developers to reacy very quickly and find the source of a problem if we have DB calls that are erroneous, or introduce performance hits (we have hundreds of thousands of DB calls per day, so one bad query can cause quite some damage).

We would also like to do this with EF. It doesn't have to be an SQL comment, but some kind of hook in order to supply meta information that is submitted with the call. Any idea whether this is possible?

Thanks for your advice

Philipp

like image 352
Philipp Sumi Avatar asked Feb 06 '14 14:02

Philipp Sumi


1 Answers

Turns out this becomes very easy with EF 6. All that's needed is an implementation of IDbCommandInterceptor, which allowed me to augment the submitted SQL with a custom (SQL) comment. That comment will appear in the database logs, and thus enable debugging / tracing from the DBA side.

public class DebugCommentInterceptor : IDbCommandInterceptor
{
    public void ReaderExecuting(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext)
    {
        command.CommandText = "/* TRACING INFORMATION GOES HERE */ " + command.CommandText;
    }

    public void NonQueryExecuting(DbCommand command, DbCommandInterceptionContext<int> interceptionContext)
    {
        command.CommandText = "/* TRACING INFORMATION GOES HERE */ " + command.CommandText;
    }

    public void NonQueryExecuted(DbCommand command, DbCommandInterceptionContext<int> interceptionContext)
    {
    }

    public void ReaderExecuted(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext)
    {
    }

    public void ScalarExecuting(DbCommand command, DbCommandInterceptionContext<object> interceptionContext)
    {
    }

    public void ScalarExecuted(DbCommand command, DbCommandInterceptionContext<object> interceptionContext)
    {
    }
}

In order to get the above interceptor operational, I simply registered it with the static DbInterception class:

DbInterception.Add(new DebugCommentInterceptor());
like image 174
Philipp Sumi Avatar answered Sep 29 '22 13:09

Philipp Sumi