Entity Framework 4.0: как просмотреть инструкции SQL для метода SaveChanges
Я использовал контекст .Log для трассировки LINQ to SQL сгенерированных SQL-выражений, как показано в Sql Server Query Visualizer - Невозможно увидеть сгенерированный SQL-запрос
context.Log = new OutputWindowWriter();
Для EF, есть ли что-нибудь подобное и простое, как вышеприведенный подход?
Ответы
Ответ 1
В общем, вы можете подключить встроенный трассировщик или любой регистратор простым
context.Database.Log = msg => Trace.WriteLine(msg);
в конструкторе DbContext.
См. Больше в MSDN. Некоторые другие подходы из MS здесь (все на основе DataContext.Log).
Говоря о решении Clutch, упомянутом Nate, оно не работает с EF v6 (см. этот отчет об ошибке).
СПИСОК ЛИТЕРАТУРЫ
Ответ 2
The Clutch.Diagnostics.EntityFramework(доступно в NuGet) отлично работает для меня, и это проще, чем EFTracingProvider.
UPDATE для EF 6:
Начиная с Entity Framework 6, в любое время, когда Entity Framework отправляет команду в базу данных, эта команда может быть перехвачена кодом приложения. Это чаще всего используется для ведения журнала SQL, но также может использоваться для изменения или отмены команды.
В частности, EF включает:
* Свойство Log для контекста, подобного DataContext.Log в LINQ to SQL.
* Механизм настройки содержимого и форматирования вывода, отправленного в журнал.
* Низкоуровневые строительные блоки для перехвата, обеспечивающие больший контроль/гибкость.
См. http://msdn.microsoft.com/en-US/data/dn469464
Ответ 3
EF Tracing Provider может выводить все операторы SQL, выполняемые как трассировки. Вы также можете использовать его, чтобы добавить свой собственный журнал, если хотите. Здесь некоторый код, который вы могли бы поместить в конструктор вашего контекстного класса (это для DBContext, но настройка, использующая ObjectContext, должна быть довольно очевидной):
// enable logging all queries executed by EF
var cx = ((IObjectContextAdapter)this).ObjectContext; // change to var cx = this; if using ObjectContext.
cx.EnableTracing();
cx.Connection.GetTracingConnections().ToList().ForEach(
c =>
{
c.CommandExecuting += (s, e) => Log(e);
c.CommandFailed += (s, e) => Log(e);
c.CommandFinished += (s, e) => Log(e);
});
Ответ 4
Множество решений для этого, но простейшее в коде - это просто вызвать ToString() в IQueryable оператора LINQ.
var query = db.Employees.Where(x => x.ID = 1); //query will be an IQueryable object
var sql = query.ToString();
Это только в EF4.1 (ранее вызов ToTraceString в ObjectQuery был способом достижения этого).
Ответ 5
Расширение ответа Nate для EF6, NLogCommandInterceptor
в Запись и перехват операций с базой данных показывает только CommandText.
Если было какое-то определенное значение параметра, из-за которого сбой команды commandText, значения параметров не испускаются в журнал. В моем случае я хотел зарегистрировать, какие значения вызывают нарушения внешнего ключа.
Это можно улучшить, изменив метод NLogCommandInterceptor LogIfError
, например,
private void LogIfError<TResult>(DbCommand command, DbCommandInterceptionContext<TResult> interceptionContext)
{
if (interceptionContext.Exception != null)
{
var commandDumper = new DbCommandDumper(command);
Log.Warn(Command failed:\r\n{0}", commandDumper.GetLogDump());
// Exception will get logged further up the stack
}
}
где класс DbCommandDumper восстанавливает DbCommand в TSQL, который может быть воспроизведен в тестовую базу данных.
Ответ 6
Я считаю, что вы можете использовать метод ToTraceString экземпляра ObjectQuery, который у вас есть.
Другим подходом было бы взглянуть на IntelliTrace Visual Studion, поскольку он регистрирует SQL, выходящий из вашего проекта.