Skip to content

Instantly share code, notes, and snippets.

@watfordgnf
Created April 16, 2019 15:26
Show Gist options
  • Save watfordgnf/e949f178516488bb7bc578dd2e48dbcc to your computer and use it in GitHub Desktop.
Save watfordgnf/e949f178516488bb7bc578dd2e48dbcc to your computer and use it in GitHub Desktop.
TracingCommandInterceptor: Entity Framework "tracing" with call stack injection into SQL commands
using System;
using System.Data.Common;
using System.Data.Entity;
using System.Data.Entity.Infrastructure.Interception;
using System.Diagnostics;
using System.Reflection;
using System.Text;
namespace TracingInterception
{
/// <summary>
/// Provides tracing for EntityFramework calls by injecting stack traces as comments before each SQL call.
/// </summary>
public class TracingCommandInterceptor : IDbCommandInterceptor
{
/// <inheritdoc/>
public void NonQueryExecuted(DbCommand command, DbCommandInterceptionContext<int> interceptionContext) { }
/// <inheritdoc/>
public void NonQueryExecuting(DbCommand command, DbCommandInterceptionContext<int> interceptionContext)
{
command.CommandText = command.CommandText + "\n" + GetCallStackComment();
}
/// <inheritdoc/>
public void ReaderExecuted(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext) { }
/// <inheritdoc/>
public void ReaderExecuting(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext)
{
command.CommandText = command.CommandText + "\n" + GetCallStackComment();
}
/// <inheritdoc/>
public void ScalarExecuted(DbCommand command, DbCommandInterceptionContext<object> interceptionContext) { }
/// <inheritdoc/>
public void ScalarExecuting(DbCommand command, DbCommandInterceptionContext<object> interceptionContext)
{
command.CommandText = command.CommandText + "\n" + GetCallStackComment();
}
/// <summary>
/// Gets the call stack as a SQL comment.
/// </summary>
/// <remarks>
/// This ignores everything in EntityFramework and this tracing interceptor.
/// </remarks>
/// <returns>An SQL Server comment containing the current stack trace.</returns>
private static string GetCallStackComment()
{
var stackTrace = new StackTrace();
var builder = new StringBuilder();
for (int ii = 0; ii < stackTrace.FrameCount; ++ii)
{
StackFrame frame = stackTrace.GetFrame(ii);
MethodBase method = frame.GetMethod();
if (method.DeclaringType == typeof(TracingCommandInterceptor)
|| method.Module.Assembly.FullName.StartsWith("EntityFramework", StringComparison.OrdinalIgnoreCase))
{
continue;
}
builder.Append("-- " + frame.ToString() + "\n");
}
return builder.ToString();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment