Я сделал это, создав класс оболочки вокруг ObjectContext и используя эту оболочку вместо исходного контекста. Вот пример контекстной оболочки:
public partial class LoggedContext : MyContext
{
public LoggedContext()
: this("name=MyEntities") // Adjust this to match your entities
{
}
public LoggedContext(string connectionString)
: base(EntityConnectionWrapperUtils.CreateEntityConnectionWithWrappers(connectionString)
{
}
private EFTracingConnection TracingConnection
{
get { return this.UnwrapConnection<EFTracingConnection>(); }
}
public event EventHandler<CommandExecutionEventArgs> CommandExecuting
{
add { this.TracingConnection.CommandExecuting += value; }
remove { this.TracingConnection.CommandExecuting -= value; }
}
public event EventHandler<CommandExecutionEventArgs> CommandFinished
{
add { this.TracingConnection.CommandFinished += value; }
remove { this.TracingConnection.CommandFinished -= value; }
}
public event EventHandler<CommandExecutionEventArgs> CommandFailed
{
add { this.TracingConnection.CommandFailed += value; }
remove { this.TracingConnection.CommandFailed -= value; }
}
}
У меня также есть статический класс, который определяет метод вывода трассировки и имеет статический метод для инициализации трассировки. Здесь:
public static class EFTracingExtensions
{
private static ILogger _logger;
public static void InitSqlTracing(ILogger logger)
{
_logger = logger;
EFTracingProviderConfiguration.RegisterProvider();
if (logger.IsLoggingEnabled()) // Don't add logging hooks if logging isn't enabled
{
EFTracingProviderConfiguration.LogAction = new Action<CommandExecutionEventArgs>(AppendSqlLog);
}
}
private static void AppendSqlLog(CommandExecutionEventArgs e)
{
if (e.Status != CommandExecutionStatus.Executing) // we only care about Finished and Failed
{
StringBuilder msg = new StringBuilder(e.ToTraceString().TrimEnd());
msg.Append(Environment.NewLine);
if (e.Result is SqlDataReader)
{
int rows = ((SqlDataReader)e.Result).HasRows ? ((SqlDataReader)e.Result).RecordsAffected : 0;
msg.AppendFormat("*** {0} rows affected", rows);
}
else if (e.Result is int)
{
msg.AppendFormat("*** result: {0}", e.Result);
}
else
{
msg.AppendFormat("*** finished, result: {0}", e.Result);
}
msg.Append(Environment.NewLine);
msg.AppendFormat(" [{0}] [{1}] in {2} seconds", e.Method, e.Status, e.Duration);
_logger.Log(msg.ToString(), LoggerCategories.SQL);
}
}
}
ILogger - это интерфейс регистрации, который я использую. Вам необходимо заменить свой собственный интерфейс / методы.
Метод InitSqlTracing вызывается один раз при запуске моей программы, а затем класс LoggedContext используется для регистрации всего SQL, сгенерированного Entity Framework.
Собираем все вместе с вашим примером кода:
EFTracingExtensions.InitSqlTracing(logger); // only call this once
using (var context = new LoggedContext())
{
var a = from data in context.Projects select data;
}