如何查看nHibernate生成的SQL?

如何查看nHibernate生成的SQL?,nhibernate,Nhibernate,如何查看nHibernate生成的SQL?版本1.2使用sql server探查器 编辑(1年后):正如@Toran Billups在下面所述,Ayende编写的NHibernate探查器非常酷。在配置设置中,将“show_sql”属性设置为true。 这将导致SQL输出到NHibernate的日志文件中,由log4net提供。关于NHibernate的日志记录,有一个很好的参考:。它包括有关记录所有NHibernate生成的SQL语句的信息。您可以在app.config/web.config文

如何查看nHibernate生成的SQL?版本1.2使用sql server探查器


编辑(1年后):正如@Toran Billups在下面所述,Ayende编写的NHibernate探查器非常酷。

在配置设置中,将“show_sql”属性设置为true。
这将导致SQL输出到NHibernate的日志文件中,由log4net提供。

关于NHibernate的日志记录,有一个很好的参考:。它包括有关记录所有NHibernate生成的SQL语句的信息。

您可以在app.config/web.config文件中放置类似的内容:

在configSections节点中:

<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net"/>
在应用程序启动时,或

[assembly: log4net.Config.XmlConfigurator(Watch=true)]
在assemblyinfo.cs中


在配置设置中,将“show_sql”属性设置为true。

是一个选项,如果您必须执行任何重要操作。

您也可以尝试(如果没有其他操作,则30天试用)。这是IMHO最好的工具


这不仅会显示生成的SQL,还会显示警告/建议/etc

如果您使用的是SQL Server(非Express),您可以尝试SQL Server Profiler。

我知道我有点晚了,但这确实起到了作用,而且它与工具/db/框架无关。 我使用的不是那些有效的选项

首先,实现一个类,该类扩展了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);
        }
    }
}
然后,在打开会话时只需传递一个实例。请确保仅在调试时执行此操作:

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();
var totalPostScont=Database.Session.Query().Count();
var currentPostPage=Database.Session.Query()
.OrderByDescending(c=>c.CreatedAt)
.Skip((第1页)*PostsPerPage)
.拍摄(后期照片)
.ToList();
。。在输出窗口中直接显示:

NH:从post0中选择cast(count(*)as INT)作为col_0_0__

NH:选择post0\u.Id作为Id3\u,选择post0\u.user\u Id作为user2\u 3\u,选择post0\u.Title作为 标题3,post0,Slug为Slug3,post0为Content3, post0_uu.创建时为created6_u3_u,post0_u.更新时为updated7_u3_u, post0。已从post0中删除,按顺序从post0中删除 在desc limit处创建了post0?抵消


或者,如果要显示特定查询的SQL,请使用以下方法(稍微更改了建议的版本):

并向其传递一个
NHibernate
查询,即

var query = from a in session.Query<MyRecord>()
  where a.Id == "123456" 
  orderby a.Name
  select a;

var sql = NHibernateSql(query);
var query=来自会话中的。query()
其中a.Id==“123456”
按名称排序
选择一个;
var sql=NHibernateSql(查询);

您只要求查看;但这个答案解释了如何将其记录到文件中。登录后,您可以在任何文本编辑器中查看它

NHibernate的最新版本支持通过代码进行日志记录。下面是演示这一点的示例代码。请阅读评论以便更好地理解

Configuration配置=新配置();
SetProperty(NHibernate.Cfg.Environment.dial,…);
//根据需要设置其他configuration.SetProperty
SetProperty(NHibernate.Cfg.Environment.ShowSql,“true”)//启用ShowSql
SetProperty(NHibernate.Cfg.Environment.FormatSql,“true”)//启用FormatSql使日志可读;可选。
configuration.AddMapping(……);
BuildMappings();
ISessionFactory sessionFactory=configuration.BuildSessionFactory();
//ISessionFactory目前已建立。现在,配置日志记录。
层次结构=(层次结构)LogManager.GetRepository(Assembly.GetEntryAssembly());
hierarchy.Root.RemoveAllAppenders();
FileAppender FileAppender=新FileAppender();
fileAppender.Name=“NHFileAppender”;
fileAppender.File=logFilePath;
fileAppender.AppendToFile=true;
fileAppender.LockingModel=新建fileAppender.MinimalLock();
fileAppender.Layout=newpatternLayout(“%d{yyyyy-MM-dd HH:MM:ss}:%m%n%n”);
fileAppender.ActivateOptions();
Logger Logger=hierarchy.GetLogger(“NHibernate.SQL”)作为记录器;
logger.Additivity=false;
logger.Level=Level.Debug;
logger.AddAppender(fileAppender);
hierarchy.Configured=true;

您可以根据需要进一步使用
FileAppender
Logger
。有关更多详细信息,请参阅答案和参考资料。这解释了XML配置的相同之处;但这同样适用于代码。

Nice。我忘了。单击此按钮不会为我显示完整的SQL。我看不到实际值,类似这样:`SELECT application0_uu.ApplicationId as app===App1_101_u,application0_u.ApplicationNumberCounty as ApplicationNu2_101_1…`我发现要在调试级别记录SQL,所以您可能希望确保您的记录器级别是调试的。我的最终目标是从NHibernate读取SQL,请参阅配置设置?那在哪里?想知道在哪里设置“show_sql”。这是在hibernate配置xml文件中。新版本的NHibernate代码也可以实现同样的效果。我已经在中解释过了。不适用于SQL CE(即使它被宣传为这样),只是FYIThis起作用。我想补充一点,新的API是
sessionFactory.WithOptions().Interceptor(新的SQLDebugOutput()).OpenSession()
。这样,如果除此之外还有更多的拦截器,我们可以简单地将它们链接到您的
拦截器之后。
 var totalPostsCount = Database.Session.Query<Post>().Count();
 
 var currentPostPage = Database.Session.Query<Post>()
        .OrderByDescending(c => c.CreatedAt)
        .Skip((page - 1) * PostsPerPage)
        .Take(PostsPerPage)
        .ToList();
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;
}
var query = from a in session.Query<MyRecord>()
  where a.Id == "123456" 
  orderby a.Name
  select a;

var sql = NHibernateSql(query);