2012-08-24 97 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的陳述。