Created
April 16, 2019 15:26
-
-
Save watfordgnf/e949f178516488bb7bc578dd2e48dbcc to your computer and use it in GitHub Desktop.
TracingCommandInterceptor: Entity Framework "tracing" with call stack injection into SQL commands
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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