Подтвердить что ты не робот

Entity Framework 4.0: как просмотреть инструкции SQL для метода SaveChanges

Я использовал контекст .Log для трассировки LINQ to SQL сгенерированных SQL-выражений, как показано в Sql Server Query Visualizer - Невозможно увидеть сгенерированный SQL-запрос

context.Log = new OutputWindowWriter();

Для EF, есть ли что-нибудь подобное и простое, как вышеприведенный подход?

4b9b3361

Ответ 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, выходящий из вашего проекта.