2010-03-19 63 views
1

这是一个非常简单的问题。当我这样做:NHibernate列表是否按需加载?

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

由此产生的IList将加载,因为我访问它?比方说,例如从100到100个元素?或者它会一次加载?

如果不是“虚拟”,我该如何做到这一点?关于它的最佳实践是什么?

谢谢;

回答

2

当您调用List()方法时,查询将被执行(并一次加载)。如果在访问实体时加载实体,会导致一些潜在的“选择N + 1”查询,这会降低您的应用程序的运行速度,并且在实时运行之前您可能不会注意到它。

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

底线是它听起来像是一个非常好的主意,当你访问它们时加载实体。但在很多情况下,它会导致一些严重的问题(如选择N + 1查询),可能会导致您的应用程序中断。

配置nhibernate的一个很好的工具是nhprof。如果你还没有检查出来,我真的会推荐它。

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); 
+0

Kibbled,感谢您的回复。我不知道未来。未来会一次加载还是需要加载? (例如,当我迭代它时,每次加载100条记录) – 2010-03-21 09:07:54

+0

未来只会延迟执行。它不会批量选择。如果要批量检索,则在类级别上(在HBM文件中)具有批处理大小属性。我之前没有在该级别使用批处理。 如果批处理是你正在寻找的东西,你可以在你的DAO本身启用批处理。这种模式与使用NHibernate进行自定义分页相似。 – 2010-03-21 18:27:47

1

随着列出所有在用,你必须使用未来其他查询批处理只有一个往返一次 随着未来的一次。 一次枚举Enumerable,但会在迭代期间实例化实体。

+0

感谢您的回复法比奥。您能否更好地解释一下“只用一次往返与您使用过Future的其他查询进行往返”的短语?提前致谢。 – 2010-03-21 09:08:43