NHibernate:Criteria查询在Web应用程序中运行缓慢,但在单元测试中运行速度快,为什么?

时间:2011-07-21 14:20:56

标签: asp.net nhibernate

我遇到的问题是,当我在单元测试中运行时,NHibernate中的条件查询执行的时间不到一秒,但是当我尝试从我的Web应用程序的上下文中运行它时,它需要一分钟。对于相同的数据,两者都在同一个数据库中。

我的NHibernate映射:

var properties = new Dictionary<string, string>();
var configuration = new Configuration();

properties.Add("connection.provider", "NHibernate.Connection.DriverConnectionProvider");
properties.Add("proxyfactory.factory_class", "NHibernate.Bytecode.DefaultProxyFactoryFactory, NHibernate");
properties.Add("connection.release_mode", "on_close");
properties.Add("current_session_context_class", "web");
properties.Add("dialect", "NHibernate.Dialect.MsSql2005Dialect");
properties.Add("connection.connection_string_name", "DBConnection");
configuration.Properties = properties;
SessionFactory = configuration.BuildSessionFactory();

测试和Web应用程序之间的这种映射的唯一区别是current_session_context_class,它在测试中是thread_static,但这似乎不是问题。

查询的标准:

var reports =   Session.CreateCriteria<Report>()
        .SetFetchMode("Site", FetchMode.Join)
        .SetFetchMode("Actions", FetchMode.Join)
        .SetResultTransformer(new DistinctRootEntityResultTransformer())
        .Add(Subqueries.PropertyIn("Site",
            SiteCriteria.GetSitesForUserWithPermission(user, Permission.SomePermission))))
        .List<Report>();

我尝试使用NH Profiler提供帮助,但它没有提供任何有用的建议。

编辑:在nhprofiler中进一步看,我看到在测试中,例如,查询持续时间是1ms / 313ms(仅数据库/总计)。 但对于该网站,它只花了我1ms / 43698ms。 NHibernate似乎很难映射实际的对象。

2 个答案:

答案 0 :(得分:4)

单元测试和Web应用程序之间的区别在于不记录单元测试。 我添加到log4net.config:

<filter type="log4net.Filter.LevelRangeFilter">
    <levelMin value="WARN" />
</filter>

问题消失了。

输出了很多这样的东西:

2011-07-21 13:07:17,479 DEBUG [14] LoadContexts - attempting to locate loading collection entry [CollectionKey[Actions#d6adfe87-a7d4-4821-bb10-4ef76fcf614d]] in any result-set context
2011-07-21 13:07:17,481 DEBUG [14] LoadContexts - collection [CollectionKey[Actions#d6adfe87-a7d4-4821-bb10-4ef76fcf614d]] not located in load context

答案 1 :(得分:0)

Visual Studio Debugger是罪魁祸首!尝试通过调试关闭(ctrl + F5)来运行您的应用程序,或者从visual studio外部运行它。我做了这个,我的应用程序运行速度与单元测试一样快。

如果这样可以解决问题,那么可以采取一些措施来加速VS Debugger,例如删除所有断点并删除.suo文件。有关详细信息,请参阅此帖子:Slow debugging issue in Visual Studio

其他可能有用的事情:

  1. 尝试为您连接的用户设置正确的默认数据库。在sql server本身(例如使用SSMS)上执行此操作,而不是在任何配置中。
  2. 使用app / web config中的阈值属性完全关闭log4net日志记录:<log4net debug="false" threshold="off">
  3. 在hibernate配置中设置default_schema。
  4. 在hibernate配置中关闭show_sql。