當你執行今後的查詢,你拉的所有父母與子女對象爲1級高速緩存。父對象包含需要填充的惰性集合。爲了填充集合,NHibernate必須查詢數據庫。 (我們將在短短一秒鐘內找到原因。)查詢返回Child對象,這些子對象已經在L1緩存中。所以這些對象被用來填充集合。
現在爲什麼NHibernate必須查詢數據庫來填充Childs集合?你可以在集合上有一個「where」子句,用IsDeleted == true過濾出Child對象。您可以在EventListener中的代碼中篩選出某些Child對象。基本上可以發生很多事情,NHibernate不能對Parent和Child對象之間的關係做任何假設。
您可以通過在HQL或映射中指定獲取策略來爲其提供足夠的信息。在HQL中,您可以編寫:
var parents = session.CreateQuery("from Parent p join fetch p.Childs").Future<Parent>();
使用未來的子對象查詢將是完全可選的,因爲您正在使用父項獲取子項。由於聯合提取,您將獲得重複的父對象,儘管它們將是同一個對象。 (你正在數據庫中做一個內部連接,併爲每個子行返回一個父行的副本。)你可以通過在parents.Distinct()上迭代來擺脫這些。
如果您始終想要使用相應的Parent獲取子對象,則還可以在您的父映射中使用fetch =「join」。
<bag name="Children" cascade="all-delete-orphan" fetch="join">
<key column="ParentId"/>
<one-to-many class="Child"/>
</bag>
如果這些選項都不適用於您的方案,則可以在集合映射上指定批處理大小。當你點擊parent.Child時,你仍然會執行一個數據庫查詢,但是NHibernate會急切地初始化任何其他集合代理。
<bag name="Children" cascade="all-delete-orphan" batch-size="10">
<key column="ParentId"/>
<one-to-many class="Child"/>
</bag>