是否按需加载NHibernate列表?

时间:2010-03-19 09:33:09

标签: nhibernate

这是一个非常简单的问题。当我这样做时:

session.CreateCriteria(typeof(Product)).List();

生成的IList会在我访问时加载吗?比方说,例如100到100个元素?或者它会一次加载吗?

如果它不是“虚拟”,我怎么能这样做?关于它的最佳实践是什么?

感谢;

3 个答案:

答案 0 :(得分:2)

当您调用List()方法时,将执行查询(并立即加载所有内容)。如果它在您访问实体时会加载实体,则会导致一些潜在的“选择N + 1”查询,这些查询可能会使您的应用程序大量减速,并且您可能在它生存之前就没有注意到它。

我想说在大多数情况下,您确实希望在调用List()方法时执行查询,而是在查询中指定所需的行。但是,您可以使用linq to nhibernate并使用IQueryable接口来限制稍后的结果集。

最重要的是,在访问实体时加载实体可能听起来是个好主意。但在许多情况下,它会导致一些可能导致应用程序无法解决的严重问题(如选择N + 1查询)。

配置nhibernate的一个非常好的工具是nhprof。如果您还没有检查过,我会推荐它。

答案 1 :(得分:1)

NHibernate有一个名为Futures的功能,它将延迟执行查询以供日后使用。例如:

class MyDao
  public IEnumerable<Product> GetProducts()
    return session.CreateCriteria(typeof(Product)).Future<Product>;


var list = MyDao.GetProducts(); // this has not be executed yet
... // some other code here
// query has not been executed yet

foreach (var o in list) // this will cause the query to be executed via IEnumerable
  Console.WriteLine(o.Name);

答案 2 :(得分:1)

立即使用List 使用Future,只需一次往返,与其他查询一起使用Future。 使用Enumerable,但会在迭代期间实例化实体。