如何查看 nHibernate 生成的 SQL?1.2版
10 回答
你可以在你的 app.config/web.config 文件中加入这样的东西:
在 configSections 节点中:
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net"/>
在配置节点中:
<log4net>
<appender name="NHibernateFileLog" type="log4net.Appender.FileAppender">
<file value="logs/nhibernate.txt" />
<appendToFile value="false" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%d{HH:mm:ss.fff} [%t] %-5p %c - %m%n" />
</layout>
</appender>
<logger name="NHibernate.SQL" additivity="false">
<level value="DEBUG"/>
<appender-ref ref="NHibernateFileLog"/>
</logger>
</log4net>
别忘了打电话
log4net.Config.XmlConfigurator.Configure();
在你的应用程序启动时,或者把
[assembly: log4net.Config.XmlConfigurator(Watch=true)]
在 assemblyinfo.cs
在配置设置中,将“show_sql”属性设置为 true。
我知道我有点晚了,但这可以解决问题,而且它是独立于工具/数据库/框架的。而不是那些有效的选项,我使用NH Interceptors。
首先,实现一个扩展NHibernate.EmptyInterceptor并实现NHibernate.IInterceptor的类:
using NHibernate;
namespace WebApplication2.Infrastructure
{
public class SQLDebugOutput : EmptyInterceptor, IInterceptor
{
public override NHibernate.SqlCommand.SqlString
OnPrepareStatement(NHibernate.SqlCommand.SqlString sql)
{
System.Diagnostics.Debug.WriteLine("NH: " + sql);
return base.OnPrepareStatement(sql);
}
}
}
然后,只需在您打开会话时传递一个实例。请务必仅在 DEBUG 中执行此操作:
public static void OpenSession() {
#if DEBUG
HttpContext.Current.Items[SessionKey] = _sessionFactory.OpenSession(new SQLDebugOutput());
#else
HttpContext.Current.Items[SessionKey] = _sessionFactory.OpenSession();
#endif
}
就是这样。
从现在开始,你的 sql 命令像这样......
var totalPostsCount = Database.Session.Query<Post>().Count();
var currentPostPage = Database.Session.Query<Post>()
.OrderByDescending(c => c.CreatedAt)
.Skip((page - 1) * PostsPerPage)
.Take(PostsPerPage)
.ToList();
.. 直接显示在您的输出窗口中:
NH:从帖子 post0_ 中选择 cast(count(*) as INT) as col_0_0_
NH:选择post0_.Id 作为Id3_,post0_.user_id 作为user2_3_,post0_.Title 作为Title3_,post0_.Slug 作为Slug3_,post0_.Content 作为Content3_,post0_.created_at 作为created6_3_,post0_.updated_at 作为updated7_3_,post0_.deleted_at 作为deleted8_3_从帖子 post0_ order by post0_.created_at desc 限制?抵消 ?
在配置设置中,将“show_sql”属性设置为 true。这将导致 SQL 在 NHibernate 的日志文件中输出,由 log4net 提供。
使用 sql 服务器分析器。
编辑(1 年后):正如@Toran Billups 下面所述,NHibernate 分析器 Ayende 写的非常酷。
您也可以尝试NHibernate Profiler(如果没有别的,可以试用 30 天)。这个工具是最好的恕我直言。
这不仅会显示生成的 SQL,还会显示警告/建议/等
NHibernate 日志记录有一个很好的参考:How to configure Log4Net for use with NHibernate。它包括有关记录所有 NHibernate 生成的 SQL 语句的信息。
Nhibernate Profiler是一个选项,如果你必须做一些严肃的事情。
如果您使用的是 SQL Server(不是 Express),则可以尝试 SQL Server Profiler。
或者,如果您想显示特定查询的 SQL,请使用以下方法(稍微改变了Ricardo Peres建议的版本):
private String NHibernateSql(IQueryable queryable)
{
var prov = queryable.Provider as DefaultQueryProvider;
var session = prov.Session as ISession;
var sessionImpl = session.GetSessionImplementation();
var factory = sessionImpl.Factory;
var nhLinqExpression = new NhLinqExpression(queryable.Expression, factory);
var translatorFactory = new NHibernate.Hql.Ast.ANTLR.ASTQueryTranslatorFactory();
var translator = translatorFactory.CreateQueryTranslators(nhLinqExpression, null, false, sessionImpl.EnabledFilters, factory).First();
var sql = translator.SQLString;
var parameters = nhLinqExpression.ParameterValuesByName;
if ( (parameters?.Count ?? 0) > 0)
{
sql += "\r\n\r\n-- Parameters:\r\n";
foreach (var par in parameters)
{
sql += "-- " + par.Key.ToString() + " - " + par.Value.ToString() + "\r\n";
}
}
return sql;
}
并传递给它一个NHibernate
查询,即
var query = from a in session.Query<MyRecord>()
where a.Id == "123456"
orderby a.Name
select a;
var sql = NHibernateSql(query);
您只要求查看;但是这个答案解释了如何将它记录到文件中。登录后,您可以在任何文本编辑器中查看它。
最新版本的 NHibernate 支持通过代码启用日志记录。以下是演示这一点的示例代码。请阅读评论以更好地理解。
Configuration configuration = new Configuration();
configuration.SetProperty(NHibernate.Cfg.Environment.Dialect, ......);
//Set other configuration.SetProperty as per need
configuration.SetProperty(NHibernate.Cfg.Environment.ShowSql, "true"); //Enable ShowSql
configuration.SetProperty(NHibernate.Cfg.Environment.FormatSql, "true"); //Enable FormatSql to make the log readable; optional.
configuration.AddMapping(......);
configuration.BuildMappings();
ISessionFactory sessionFactory = configuration.BuildSessionFactory();
//ISessionFactory is setup so far. Now, configure logging.
Hierarchy hierarchy = (Hierarchy)LogManager.GetRepository(Assembly.GetEntryAssembly());
hierarchy.Root.RemoveAllAppenders();
FileAppender fileAppender = new FileAppender();
fileAppender.Name = "NHFileAppender";
fileAppender.File = logFilePath;
fileAppender.AppendToFile = true;
fileAppender.LockingModel = new FileAppender.MinimalLock();
fileAppender.Layout = new PatternLayout("%d{yyyy-MM-dd HH:mm:ss}:%m%n%n");
fileAppender.ActivateOptions();
Logger logger = hierarchy.GetLogger("NHibernate.SQL") as Logger;
logger.Additivity = false;
logger.Level = Level.Debug;
logger.AddAppender(fileAppender);
hierarchy.Configured = true;
您可以根据自己的需要FileAppender
进一步玩。Logger
有关更多详细信息,请参阅此答案和此资源。这与 XML 配置解释相同;但同样适用于代码。