2011-04-12 22 views
0

我有一個對象表和對象別名表。nhibernate集合集合映射避免n + 1選擇和重複行以獲取連接

別名只是字符串的一組集合:

object.Aliases 

如果我映射這樣的集合:

<class name="Object" table="Object" lazy="false"> 
    ... 
    properties... 
    ... 
    <set name="Aliases" table="Aliases" inverse="true" lazy="false" fetch="join" > 
     <key column="ObjectId" /> 
     <element column="Name" type="String"/> 
    </set> 
    ... 
</class> 

然後

session.CreateCriteria(typeof (T)).List<T>(); 

從基地寶庫,它獲取所有對象,返回每個別名的重複項。爲什麼?我如何擺脫列表中的重複對象?

謝謝大家的時間。

編輯: 更新的映射...但這就是所有的映射。別名沒有它自己的類,因爲它只是需要被加載到ISet<string> Object.Aliases

+0

你問關於選擇n + 1還是重複?或兩者? – Rippo 2011-04-12 15:17:53

+0

你可以發佈更多的信息,代碼和映射的兩個表 – Rippo 2011-04-12 15:19:47

+0

我要求正確的映射排除n + 1選擇,哪些不會返回重複。 如果我刪除fetch =「加入」,那麼結果是沒有重複,但有n + 1選擇問題。如果我離開獲取=「加入」,那麼我只有一個選擇,但重複的問題 至於映射..這就是它,唯一相關的部分...但我會更新更多的解釋 – 2011-04-13 07:34:18

回答

1

我被這個困惑一組字符串也是,當我開始使用NHibernate的時候。這就是它的工作原理。因爲映射包括fetch="join",所以它使用父表和子表之間的SQL JOIN,所以父數據對每個子都重複。但是,不是過濾出父項的額外實例,而是在查詢中返回每行一個對象的集合。你需要指出你想要不同的對象。使用ICriteria語法,您可以將Transformers.DistinctRootEntity添加到您的查詢中。

請參閱Get Distinct result set from NHibernate using Criteria API?及其中提到的鏈接。

+0

要小心這種方法,因爲它會給你一個'笛卡兒'的產品。根據使用情況,這可能或可能不需要。 – Rippo 2011-04-13 06:49:01

+0

謝謝你的指針。我終於設法使用客戶端列表().Distinct ()''Transformers.DistinctRootEntity'也​​做它的客戶端,但我不想混亂編寫Criteria對象。我的最終解決方案是: '返回新列表(base.GetAll()。Distinct ());' 重要提示:爲了使Discinct()能夠正常工作,您需要定義equals班已經有了,所以這很方便 – 2011-04-13 08:18:53

0

對於選擇N + 1個問題添加batch-size="10"到您的映射

<set name="Aliases" batch-size="10" ... 
+0

這幾乎是解決方案,謝謝你的指出它!我說幾乎是因爲它解決了n + 1選擇。不幸的是,我有〜970對象,我需要填充別名,我把批量大小=「100」,結果查詢是巨大的..在日誌中0.5MB的文本(總共約10個查詢)。與fetch =「join」情況相比,這是巨大的,因此我想我會看看如果我可以將DISTINCT應用於連接。 – 2011-04-13 07:57:06