NHibernate - 找到执行查询的代码

时间:2014-08-19 06:44:50

标签: c# nhibernate

我正在开展一个由其他人完成的大项目。这段代码里面有很多项目,它使用NHibernate作为ORM。数据库非常繁忙,所以我试图诊断它缓慢的地方并尝试诊断整个系统流程。

我所做的其中一件事是为NHibernate.SQL添加一个log4net,它将所有正在运行的查询输出到日志文件中:

<logger name="NHibernate.SQL" additivity="false">
    <level value="ALL" />
    <appender-ref ref="NHibernateSQLAppender" />
</logger>

这是appender:

<appender name="NHibernateSQLAppender" type="log4net.Appender.RollingFileAppender">
        <file value="NHibernateSQL.txt"></file>
        <appendToFile value="true"></appendToFile>
        <maximumFileSize value="15MB"></maximumFileSize>
        <maxSizeRollBackups value="10"></maxSizeRollBackups>
        <rollingStyle value="Size"></rollingStyle>
        <layout type="log4net.Layout.PatternLayout">
            <param name="ConversionPattern" value="%d [%t] [%line] %-5p %c [%x] &lt;%X{auth}&gt; - %m%n"></param>
        </layout>
</appender>

在日志文件中,我看到一个在短时间内运行多次的查询,我想找到运行它的代码。我能够通过表名找到hbm文件,以及它映射到的类。

我搜索了该类的引用 - 但有很多。

所以我的基本问题是如何找到运行该特定查询的代码?甚至可能吗?

由于

2 个答案:

答案 0 :(得分:1)

您是否尝试过Nhibernate Profiler?使用分析器将有所帮助,如果我记得正确,我认为你得到每个查询的堆栈跟踪?

有关探查者http://www.hibernatingrhinos.com/products/nhprof

的更多信息

答案 1 :(得分:0)

您可以在&lt; logger&gt;中设置名称(空格)。仅限NHibernate(没有.SQL),这将非常冗长。然后,您可以从ALL返回TRACE或DEBUG级别,或查找包含有用信息的特定命名空间。

你的应用程序也使用log4net吗?然后,您可以获取应用程序和NHibernate的组合日志,检查发送查询的内容。只需添加另一个&lt; logger /&gt;阻止您的应用程序的命名空间;你可以使用相同的&lt; appender&gt;!

通常,您可以在SQL查询中轻松查看数据库对象。

多次(通常是100次)相同的查询指出了臭名昭着的N + 1问题 - 通过遍历父项并初始化子集合来为多个父对象/行加载下级行/对象。例如,发送

SELECT * FROM Children WHERE ParentId=@parid /* for some 100 Parent objects. */

这是之前返回N个父对象的第一个(1)查询,以及每个父对象上的子集合的N个查询。

当程序员不熟悉NHibernate集合并实现错误时,N + 1甚至会变得更糟,或者在没有NHibernate集合映射的情况下开始编写自己的集合处理(将NHibernate理解为OR Mapper,从SQL结果中创建对象或者oherwise)。通过连接替换可能会导致过大的结果集(笛卡尔积)。

但NHibernate也是数据库访问的优化器,在会话工厂配置( adonet.batch_size 50,例如)中提供N + 1和怪物连接之间的良好方式,即批量设置,然后在每个类元素和集合属性上设置 batch-size