如何配置Fluent NHibernate将查询输出到Trace或Debug而不是Console?

And*_*ena 49 .net c# asp.net nhibernate fluent-nhibernate

如何配置Fluent NHibernate将查询输出到Trace或Debug而不是Console?我正在使用,MsSqlConfiguration.MsSql2008.ShowSql()但它没有参数,我在谷歌上找不到任何东西.

min*_*.dk 96

我可以从论坛和博客文章中看到,在我之前的很多其他人都在寻找一种方法来获取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;
    }
}
Run Code Online (Sandbox Code Playgroud)

当然,您不必在Trace.WriteLine()此处,可以将其写入日志文件或其他任何需要的文件.

在你的连接管理器中,像你这样连接你的拦截器:

protected virtual void Configure(FluentConfiguration config)
{
    config.ExposeConfiguration(x =>
                                   {
                                       x.SetInterceptor(new SqlStatementInterceptor());
                                   });
}
Run Code Online (Sandbox Code Playgroud)

这并不复杂.从我的角度来看,肯定比通过Fluent将所有这些XML推送到NHibernate更容易 - 因为Fluent将XML文件抽象化了.

请记住,您只能拥有一个拦截器 - 因此您可能需要将此功能与现有的拦截器集成,如果您已有的话.在这方面,您可能希望给它一个更广泛的名称 - 例如MyAppInterceptor,以免暗示特定目的,因为您可能希望稍后添加其他功能.

希望这对其他人有帮助!:-)

  • @ mindplay.dk我知道这是一个古老的答案,但是`base.OnPrepareStatement(sql)`仍然输出`?`s.有任何想法吗? (7认同)
  • 也许它可以填写参数?我得到`?`(问号)而不是查询中的值,如`SELECT*FROM MyObject WHERE Id =?`.我看到有一个`IEnumerable NHibernate.SqlCommand.SqlString.GetParameters()` (4认同)

Mic*_*dox 33

您可能想使用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>
Run Code Online (Sandbox Code Playgroud)

然后在打开NHibernate会话之前从代码中调用它:

log4net.Config.XmlConfigurator.Configure();
Run Code Online (Sandbox Code Playgroud)

添加对log4net DLL的引用时,请确保将其"Copy Local"属性设置为"true".

这不是特定于FluentNHibernate,它在NHibernate的任何变体中都是一样的.


Tom*_*ell 10

我没有尝试使用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()
                ;
Run Code Online (Sandbox Code Playgroud)

一句警告 - 打开此功能可以大大减慢执行速度.

  • Visual Studio中的输出窗口显示Console,Debug和Trace输出.ShowSql方法写入Console,而不是Debug或Trace.你的建议与他所说的已经做的没有什么不同. (3认同)