【问题标题】:LINQ to Nhibernate performanceLINQ to Nhibernate 性能
【发布时间】:2012-03-16 10:49:26
【问题描述】:

我正在使用 NHibernate 和 LINQ 的组合来尝试实现查询,但我担心以下查询会从数据库中拉回每个用户行,从而导致数据库延迟大、网络流量大、内存大足迹,然后过滤掉它太晚了。

public bool CheckEmailAddressIsAvailable
               (string emailAddress, IDataRepository repository)
{
     var users = from user in repository.GetItems<User>()
                 where user.EmailAddress.Equals(
                     emailAddress,
                     System.StringComparison.CurrentCultureIgnoreCase)
                 select user;

     return !(users.Any());
}

DataRepository 是 NHibernate Session 的简单包装器 我想知道的是双重的

1) 我如何记录所有正在创建的 NHibernate SQL,以便我可以密切关注正在运行的内容 和 2)我怎样才能运行上面的查询来模仿下面的SQL

select count(*) from [User] where EmailAddress = @emailAddress

【问题讨论】:

  • 我不使用 NHibernate,但您可以使用 SQL Profiler 查看您的应用程序正在运行的查询。如果您认为没有实现任何功能,我也会尝试使用 .Count != 0 而不是 .Any()
  • 1) [如何启用 sql 日志记录][1] [1]: stackoverflow.com/q/474659/671619
  • 另外,您使用的 NHibernate 版本很重要,因为带有 contrib Nhibernate.Linq 的 v2.1 很糟糕 :(

标签: c# linq nhibernate


【解决方案1】:

NHibernate 使用 log4net 进行日志记录,因此如果您已经在使用它,一种方法是在您的 app.config 文件中将 NHibernate.SQL 记录器级别设置为 DEBUG

<logger name="NHibernate.SQL">
  <level value="DEBUG"/>
</logger>

通常,与任何其他应用程序一样,您可以简单地使用 SQL Profiler 并记录查询一段时间。

关于您的 LINQ 代码,我很确定它会创建类似于下面您的 SQL 查询,但是如果没有看到 GetItems 代码就很难判断。

如果这感觉很慢,您可能需要在 EmailAddress 列上建立索引。 SQL Profiler 的好处是您可以在 Database Engine Tuning Advisor 中分​​析其日志并获得有关如何改进它的建议。

【讨论】:

  • 您将 标签放在 app.config 的哪个级别?我已经尝试了几个地方,当我添加它时它似乎根本无法加载配置
  • @user1122909:首先,您需要通过在&lt;configSections&gt; 元素中添加&lt;section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/&gt; 来定义此部分。然后,您需要添加&lt;log4net&gt; 部分,您将在其中定义日志附加程序(文件、电子邮件、事件日志)、根记录器级别,最后添加&lt;logger&gt; 元素。这就是为什么我写了如果你已经在使用它,否则简单地启动 SQL Profiler 可能会更容易。详情请查看log4net manual
【解决方案2】:

GetItems 返回什么? 如果它返回除 IQueryable() 之外的任何内容,那么您只是在执行 LINQ to Objects(内存中)。这意味着加载整个集合。

您必须返回一个 IQueryable 以允许 DB 端过滤。

查看 ISession 的 Query() 扩展方法。这会给你一个 IQueryable

【讨论】:

  • 因此,如果您从 GetItems 返回一个 IQueryable 并在 LINQ 表达式中使用它,它会进行 DB 端过滤吗?完美的!只是查看了 ISession 并没有 Query 方法。这是我需要自己编写的代码吗?
  • 正如我所说,这是一种扩展方法。检查这个 SO 线程stackoverflow.com/questions/4666665/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-06
  • 1970-01-01
相关资源
最近更新 更多