我遇到的问题是,当我在单元测试中运行时,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似乎很难映射实际的对象。
答案 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
其他可能有用的事情:
<log4net debug="false" threshold="off">
。