查询在NHibernate中出现超时错误,但在SQL Server中没有

Jav*_*p84 8 c# sql-server nhibernate timeout

我在C#中遇到了NHibernate的问题.

当它想要执行查询时,应用程序面临ADO超时错误,但是当我使用SQL事件探查器捕获查询,然后我在新的SQL Server查询中运行它时,它只需要2秒

有任何想法吗??

Jam*_*Ide 9

从SQL事件探查器捕获查询并在SSMS中运行它时,是否将其作为sp_executesql查询运行?我使用NHibernate 2.1GA遇到了类似的问题,这个答案适用于那个版本,我还没有转换为NH3.NH Profiler是一个很棒的工具,但它有助于将SQL提取为格式化查询,该查询不代表发送到服务器的实际查询.

问题是NHibernate为sp_executesql提供字符串参数的方式.字符串参数的类型为nvarchar,其长度等于值的长度.例如,此查询分别限制两列varchar(4)和varchar(20):

exec sp_executesql N'SELECT this_.Column0, this_.Column1 FROM MySchema.MyTable this_ WHERE this_.Column0 = @p0 and this_.Column1 = @p1',N'@p0 nvarchar(4),@p1 nvarchar(7)',@p0='Val0',@p1='Value01'
Run Code Online (Sandbox Code Playgroud)

对此的查询计划使用了索引扫描并花了17秒.将nvarchar更改为varchar会生成一个使用索引查找并在<2秒内执行的计划.这在SSMS中是可重复的.

根本原因是NHibnerate默认使用DbType.String而不是DbType.AnsiString用于varchar列.我的解决方案是添加一个Fluent NHibernate约定来将所有字符串映射更改为AnsiString,这导致NHibernate创建提供参数为varchar的查询.


Baz*_*nga 4

好吧,当您处理尚未提交到数据库的事务并使用在同一对象上操作的不同事务时,我看到 nhibernate 超时发生。所以我建议在您的应用程序中查找多个会话 poen 并进行确保情况并非如此,仅使用 1..

我也建议使用 nhibernate 配置文件.. http://nhprof.com/ 它是一个很酷的工具.. 它实际上显示了向数据库触发的查询和检索的行,并且也非常易于使用..您需要做的就是将连接字符串设置为您运行查询的 dB,瞧您可以看到您的所有查询,并且您可以告别 SQL 分析器。

希望有帮助。