web-dev-qa-db-ja.com

コンソールの代わりにトレースまたはデバッグにクエリを出力するようにFluent NHibernateを構成する方法は?

コンソールの代わりにトレースまたはデバッグにクエリを出力するようにFluent NHibernateを構成する方法は? MsSqlConfiguration.MsSql2008.ShowSql()を使用していますが、パラメーターがなく、Googleで何も見つかりません。

48
André Pena

フォーラムやブログの投稿から、実行前に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()する必要はありません。ログファイルなどに必要なものを書き込むことができます。

接続マネージャーで、次のようにInterceptorを接続します。

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

それほど複雑ではありません。私の観点からは、FluentがXMLファイルを抽象化するため、このXMLをFluentからNHibernateにプッシュするよりも確かに簡単です。

インターセプターは1つしか持てないことを覚えておいてください。したがって、既に持っている場合は、この機能を既存のインターセプターと統合する必要があるかもしれません。そのメモでは、より広い名前を付けたい場合があります。 MyAppInterceptor。特定の目的を暗示しないように、後で他の機能を追加したい場合があります。

これが誰かに役立つことを願っています! :-)

95
mindplay.dk

ShowSqlではなく、log4netを使用することをお勧めします。クエリをデバッグに送信するための設定を次に示します。

  <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();

Log4net DLLへの参照を追加するときは、その「ローカルコピー」プロパティを「true」に設定してください。

これはFluentNHibernateに固有のものではなく、NHibernateのどのバリアントでも同じように機能します。

33
Michael Maddox

SQL Serverでこれを試したことはありませんが、SQLiteの場合、次のコードは生成されたSQLをOutputウィンドウ(VS2008の[デバッグ]メニュー-> [ウィンドウ]-> [出力])に表示します。

[出力]ウィンドウの[出力を表示:]コンボボックスは[デバッグ]に設定する必要があります-VS2008は自動的にそれを行いました。

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

警告の言葉-これをオンにすると、実行がかなり遅くなる可能性があります。

11
Tom Bushell