【问题标题】:Is it possible to get a lazy IEnumerable from an NHibernate query using ICriteria?是否可以使用 ICriteria 从 NHibernate 查询中获取惰性 IEnumerable?
【发布时间】:2008-12-12 14:29:45
【问题描述】:

我正在使用 NHibernate,需要检索和处理多达 200 万行。理想情况下,我可以处理每一行——一次一个——而不用 NHibernate 一次加载所有 200 万个内存(因为,你知道,这很痛苦)。

我希望获得一个 IEnumerable,它会为每次读取迭代地调用数据读取器,以便我可以处理读取的数据 - 然后丢弃它。通过这样做,我节省了大量内存,并开始更快地处理结果。我还可以通过多线程和/或使用 PLinq 来提高性能。

NHibernate 的 ICriteria 可以做到这一点吗?它返回的所有内容似乎都是 IList,并且在关闭集合引用之前已完全加载。为什么是 IList 而不是 IEnumerable?!

我并不是指 NHibernate 在加载子对象或父对象时使用的传统意义上的“懒惰”。我想要一个 惰性 IEnumerable,意味着以某种方式从 ICriteria 对象获取 IEnumerable。 ICriteria 只有一个 List() 方法,可以将结果加载到 ArrayList 中。

【问题讨论】:

  • 我认为当您在 NHibernate 中执行惰性 IEnumerable 时,您开始一次查询数据库一行。如果您必须处理这么多行,那么下拉到 ADO.Net 的数据读取器可能会更容易。

标签: .net nhibernate .net-3.5


【解决方案1】:

ICriteria 没有任何返回 IEnumerable 的方法,而是 IQuery does

【讨论】:

  • 有没有办法将 ICriteria 转换为 IQuery?
  • AFAIK IQuery 用于 HQL 和 SQL(基于字符串的查询),而 ICriteria 是......好吧,标准,我看不出两者之间有任何桥梁。我觉得 ICriteria 没有实现 Enumerate 很奇怪...
  • 我也是。我正在使用 NContrib 的 Linq-NHibernate 代码,他们使用 ICriteria 实现(在查看了他们的代码之后)。我会尝试解决他们的废话。 NHibernate 何时正式支持 Linq 的任何想法(我知道它的开始就在那里)。
  • 官方 Linq 支持将在 2.1 版本中提供。
【解决方案2】:

您想要做的是将您的数据访问包装在这样的方法中:

public IEnumerable<YourObject> GetALotOfRows() {
  ..execute DataReader
  while(..read..) {
    yield return yourObject;
  }
}

现在手头没有 VS 或 nHibernate,很抱歉半伪代码。但这里的关键是使用“收益回报”。

【讨论】:

  • 我相信 NHibernate 的执行语句使它不像 OP 想要的那样 Lazy。
  • 当 OP 说 LAZY 时,我认为他的意思类似于 SqlDataReader 所做的。
  • 这就是我想要的,但我想知道如何让 NHibernate 为我做这件事,或者至少支持它。 NHibernate 递给我一个 IList....实际上,我使用 Linq 到 NHibernate(来自 NContrib),但这似乎并不重要....
【解决方案3】:

你必须逐行执行什么样的操作?我只是好奇:)。

您可以尝试对结果进行分页 - 获取前 10 个,接下来的 10 个......等等。

编辑: 所以你会有

Session.CreateCriteria(typeof(T)).SetFirstResult(0).SetMaxResults(1).UniqueResult<T>();
Session.CreateCriteria(typeof(T)).SetFirstResult(1).SetMaxResults(1).UniqueResult<T>();
Session.CreateCriteria(typeof(T)).SetFirstResult(2).SetMaxResults(1).UniqueResult<T>();

你明白了,我想这不是最好的方法,它不是 IEnumerable ......但它会起作用。您也可以执行 SetMaxResults(10) 或更大的操作,因此不要一次发送 1。

【讨论】:

  • 我将如何对结果进行分页?!我正在做的是将结果作为 CSV 文件流式传输回 HTTP 客户端。我已经实现了 CSVStream,它支持一次转换和写入一条记录。我也只需要 NHibernate 来做到这一点。来自标准。 :)
  • 没有从 ICriteria 获取 IEnumerable 的方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多