Как настроить Fluent NHibernate для вывода запросов на трассировку или отладку вместо консоли?

Как настроить Fluent NHibernate для вывода запросов на трассировку или отладку вместо консоли? Я использую MsSqlConfiguration.MsSql2008.ShowSql(), но у него нет параметров, и я ничего не могу найти в Google.

Ответ 1

Я могу видеть из сообщений форума и блога всюду, что многие другие передо мной искали способ получить инструкции SQL, поскольку они готовятся к исполнению. Ответ обычно - это нечто вроде "вы не можете", или "вы не должны".

Должен ли я или нет, что я хотел.

После нескольких часов поиска, расследования и неудачных попыток, и, наконец, я придумал это.

Запишите перехватчик:

using NHibernate;
using System.Diagnostics;

public class SqlStatementInterceptor : EmptyInterceptor
{
    public override NHibernate.SqlCommand.SqlString OnPrepareStatement(NHibernate.SqlCommand.SqlString sql)
    {
        Trace.WriteLine(sql.ToString());
        return sql;
    }
}

Конечно, вам не нужно Trace.WriteLine() здесь, вы можете записать его в файл журнала или что-то еще, что вам нужно.

В диспетчере соединений подключите ваш перехватчик так:

protected virtual void Configure(FluentConfiguration config)
{
    config.ExposeConfiguration(x =>
                                   {
                                       x.SetInterceptor(new SqlStatementInterceptor());
                                   });
}

Это не так сложно. С моей точки зрения, конечно, проще, чем пытаться получить весь этот XML, пропущенный через Fluent в NHibernate - поскольку Fluent абстрагирует XML файл.

Имейте в виду, что у вас может быть только один Interceptor - поэтому вам может понадобиться интегрировать эту функцию с существующим Interceptor, если у вас ее уже есть. В этой заметке вы можете указать более широкое имя - например, MyAppInterceptor, чтобы не подразумевать конкретную цель, потому что вы можете захотеть добавить к нему другие функции позже.

Надеюсь, это поможет кому-то еще!: -)

Ответ 2

Вероятно, вы хотите использовать log4net, а не ShowSql. Вот некоторая конфигурация для отправки запросов в Debug:

  <configSections>
    <section name="log4net"
     type="log4net.Config.Log4NetConfigurationSectionHandler,log4net" />
  </configSections>

  <log4net debug="false">
    <appender name="WindowsDebugOutput" type="log4net.Appender.DebugAppender,
         log4net">
      <layout type="log4net.Layout.PatternLayout,log4net">
        <param name="ConversionPattern"
              value="%d{ABSOLUTE} %-5p %c{1}:%L - %m%n" />
      </layout>
    </appender>

    <logger name="NHibernate.SQL" additivity="false">
      <level value="DEBUG" />
      <appender-ref ref="WindowsDebugOutput" />
    </logger>
  </log4net>

И затем вызовите это из своего кода, прежде чем открывать сеанс NHibernate:

log4net.Config.XmlConfigurator.Configure();

Когда вы добавляете ссылку на DLL log4net, убедитесь, что для свойства "Копировать локальное" установлено значение "true".

Это не относится к FluentNHibernate, он работает одинаково в любом варианте NHibernate.

Ответ 3

Я не пробовал это с SQL Server, но с SQLite следующий код покажет сгенерированный SQL в окне Выход (меню отладки → Windows → Вывод, в VS2008).

В поле "Показать выход из:" в окне "Выход" должно быть установлено "Отладка". VS2008 сделал это для меня автоматически.

            sessionFactory = Fluently.Configure()
                .Database(SQLiteConfiguration.Standard
                            .UsingFile(DbFile)
                            // Display generated SQL in Output window
                            .ShowSql()
                          )
                .Mappings(m => m.AutoMappings.Add( GetAutoPersistenceModel() ))
                .BuildSessionFactory()
                ;

Слово предупреждения - включение этого может значительно замедлить выполнение.