2009-01-22 22 views
0

我正在寫一個需要定期(例如每週)循環遍歷數據庫中數百萬條記錄的應用程序,並對每行結果執行代碼。由於表太大了,我懷疑當我調用SomeObject.FindAll()時,它正在讀取所有140萬行並嘗試返回SomeObject []中的所有行。Lazy在Castle.ActiveRecord中讀取

有沒有一種方法可以執行SomeObject.FindAll()表達式,但以更符合DBMS的方式加載值?

回答

0

不與FindAll() - 正如你所猜測的那樣,它會嘗試一次加載指定類型的所有實例(並且,根據你如何設置NHibernate可能會發出大量的SQL查詢做到這一點)。

延遲加載僅適用於對象的屬性,因此,例如,如果你有一個持久型SomeObjectContainer其中有一個屬性SomeObject以這樣一種方式,它應該匹配所有SomeObject S和與lazy="true"映射列表,然後做在該列表屬性上的foreach,你會得到你想要的,排序;默認情況下,NHibernate會爲列表中的每個元素髮出一個查詢,每次只加載一個元素。當然,讀緩存會變得巨大,所以你可能需要刷新很多。

您可以做的是發出一個HQL(甚至是嵌入式SQL)查詢來檢索所有SomeObjects的所有ID,然後一次一個地循環訪問FindByPrimaryKey中的相關對象。再次,它不是特別優雅。

說實話,在一個情況一樣,我可能會變成一個定期維護工作中一個存儲過程 - 除非你真的要在對象上運行代碼而不是莫名其妙地處理數據。它可能會惹惱對象純粹主義者,但有時候存儲過程是正確的,特別是在這種批量作業場景中。