2012-08-24 96 views
3

我看了看周围的Stackoverflow,并看到一些与NHibernate IList vs List有关的问题。我有一个我自己的问题...NHibernate的IList或列表?

由于IList的目的是要有一个lazyloaded列表,它的目的是从库中返回。毕竟,如果你的存储库调用ToList(),你正在创建一个权威对象?因此,不管你的方法是返回一个IList还是一个List,都不会有更多的延迟加载,对吗?

回答

3

如果您的存储库返回一个IQueryable,那么您将在第一次枚举它时检索结果。如果你在它上面调用ToList(),它会在这个时候检索结果,因为ToList会枚举IQueryable。

现在,延迟加载不一定会受此行为的影响:假设您有Customers和Orders。 每个客户都有一个名为CustomerOrders的属性,该属性标记为延迟加载。这意味着,当您加载您的客户列表时,仅当您尝试枚举每个客户的CustomerOrders属性时才会检索订单。 所以如果你只是在你的GetCustomers()方法的返回值上做一个ToList(),它对CustomerOrders的延迟加载没有任何影响

+0

谢谢,这不是我所能确定的,但它听起来没错。因此,无论使用何种方式,从存储库方法中恢复IList的习惯可能总是最好的。 – MattB

+0

@MattB对于懒惰,您将返回'IQueryable'或'IEnumerable',对于物化,'IList'是有道理的,原因很多。没有什么特别的理由可以涉及'List '(除非在LINQ序列的末尾使用“ToList()”,但即使在这种情况下,您也可能想要返回IList 以保持一致性并让结果隐含地上传)(是的,我意识到你现在可能已经知道了这一切,但这个答案很容易被误解,因此我的答案是......) –

1

你几乎是正确的,但混淆了一些概念,所以我会采取它从顶部。

你是对的.ToList()materializes东西。

IList只是物化列表的抽象接口。

在某些情况下,NHibernate需要IListbecause it proxies things。当使用session.QueryOver等时,您将使用List()扩展方法返回IList(已实现)或Future()返回IEnumerable(懒惰)。 QueryOver是相当稳定和完整,铺好。

在LINQ提供方,使用session.Query,你可以留在IQueryable水平有了,IEnumerable懒物化项“的查询规范”或IList。通常情况下,您将使用ToList()来实现,而AsEnumerable()(或铸造/类型转换)可以使用IEnumerable。注意:我无法做出我对LINQ提供者重新使用QueryOver的陈述。