如何配置 Fluent NHibernate 以将查询输出到 Trace 或 Debug 而不是 Console?
Posted
技术标签:
【中文标题】如何配置 Fluent NHibernate 以将查询输出到 Trace 或 Debug 而不是 Console?【英文标题】:How to configure Fluent NHibernate to output queries to Trace or Debug instead of Console? 【发布时间】:2011-01-09 05:24:49 【问题描述】:
我正在使用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());
);
没那么复杂。从我的角度来看,这肯定比试图通过 Fluent 将所有这些 XML 推送到 NHibernate 更容易——因为 Fluent 将 XML 文件抽象掉了。
请记住,您只能拥有一个拦截器 - 因此,如果您已经拥有一个拦截器,则可能需要将此功能与现有拦截器集成。在那张纸条上,您可能想给它一个更广泛的名称 - 例如MyAppInterceptor,以免暗示特定用途,因为您可能希望稍后向其添加其他功能。
【讨论】:
很好的解决方案,简单得像地狱一样,它就可以工作,将它添加到我的测试会话工厂中,尽管可以使用#if DEBUG 添加。谢谢! 也许也可以填写参数?我得到?
(问号)而不是像SELECT * FROM MyObject WHERE Id = ?
这样的查询中的值。我看到有一个IEnumerable NHibernate.SqlCommand.SqlString.GetParameters()
@Mike 将 sql.ToString()
替换为 base.OnPrepareStatement(sql)
@mindplay.dk 我知道这是一个古老的答案,但base.OnPrepareStatement(sql)
仍然输出?
s。有什么想法吗?【参考方案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="%dABSOLUTE %-5p %c1:%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 的引用时,请确保将其“Copy Local”属性设置为“true”。
这不是 FluentNHibernate 特有的,它在 NHibernate 的任何变体中都一样。
【讨论】:
Noobish 问题,但是,将这个配置文件放在 winforms 项目中的什么位置?很多 Hibernate 的文档网站都关闭了,我只是找不到将这些 XML 信息放在哪里。谢谢。 @Mike - 它应该进入项目根目录中的 app.config,在编译时将其作为我没有在 SQL Server 上尝试过,但是在 SQLite 上,以下代码将在 Output 窗口中显示生成的 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()
;
警告 - 开启此功能会大大减慢执行速度。
【讨论】:
Visual Studio 中的输出窗口显示控制台、调试和跟踪输出。 ShowSql 方法写入控制台,而不是 Debug 或 Trace。你的建议与他所说的他已经在做的没有什么不同。 @Michael - 我刚刚重新测试了这个,它完全按照描述工作! SQLite 与 SQL Server 的 FNH 接口实现可能存在差异? 这不是同一个“调试”(注意没有“跟踪”或“控制台”选项)。 :) 要查看它是否真正写入 Debug,请使用 technet.microsoft.com/en-us/sysinternals/bb896647.aspx以上是关于如何配置 Fluent NHibernate 以将查询输出到 Trace 或 Debug 而不是 Console?的主要内容,如果未能解决你的问题,请参考以下文章
更改 NHibernate 中的初始 LazyLoad 行为
在使用fluent-nhibernate配置nhibernate时,为什么会出现MissingMethodException?