2014-01-24 99 views
1

所有,NHibernate的 - 重複記錄與懶洋洋地映射集合

我有一個實體,一個具有多個集合, - 每個集合映射懶洋洋地。當我運行標準查詢時,結果集中的根實體出現重複結果。當我的所有藏品都被懶惰地映射時,這有多可能!

我驗證了我的藏品,懶洋洋地裝載着。

這裏是我的映射:

根實體 '項目':

[Bag(0, Lazy = CollectionLazy.True, Inverse = true, Cascade = "all-delete-orphan")] 
    [Key(1, Column = "job_id")] 
    [OneToMany(2, ClassType = typeof(ProjectPlan))] 
    public virtual IList<ProjectPlan> PlanList 
    { 
     get { return _planList; } 
     set { _planList = value; } 
    } 

的標準查詢是:

ICriteria criteria = session.Session.CreateCriteria<Entities.Project>() 
        .Add(Restrictions.Eq(Entities.Project.PROP_STATUS, !Entities.Project.STATUS_DELETED_FLAG)); 
        .CreateAlias(Entities.Project.PROP_PLANLIST, "p") 
        .Add(Restrictions.Eq("p.County", 'MIDDLSEX')) 
.setFirstResult(start).setMaxResults(pageSize) 
        .List<Entities.Project>(); 

我知道,我可以糾正這個問題瓦特/鮮明的結果變壓器,我只是想知道這是否是懶惰集合上的正常行爲。

編輯:我找到了原因, - 當查看原始SQL,連接和where子句是正確的,但讓我感到困惑的是生成的Select子句, - 它不僅包含項目實體的列根實體),還包括來自項目計劃實體的列,這些列導致我上面描述的問題。我現在不在工作,但我會嘗試這樣做:.SetProjection(Projections.RootEntity()),所以我只在Select子句中獲得Project的列。

+0

我想我發現了我的問題的副本:http://floledermann.blogspot.ca/2007/10/solving-hibernate-criterias-distinct.html – ActiveX

+0

後續行動上面的博客,看起來像.setFirstResult(開始).setMaxResults(pageSize)是EVIL! – ActiveX

回答

1

的一種方式,如何解決這個(我說那麼平常的情況)是:1)不使用取查詢的內部集合和2)使用批量抓取,作爲映射的一部分

所以,我們將一直在查詢根實體。這會給我們一個扁平的結果集,其中可以被正確地用於分頁

以獲得每個收到行收集數據,並避免1個+ N問題(goign爲每條記錄的集合),我們將使用19.1.5. Using batch fetching

映射會是這樣

[Bag(0, Lazy = CollectionLazy.True 
     , Inverse = true 
     , Cascade = "all-delete-orphan" 
     , BatchSize = 25)] // Or something similar to batch-size="25" 
[Key(1, Column = "job_id")] 
[OneToMany(2, ClassType = typeof(ProjectPlan))] 
public virtual IList<ProjectPlan> PlanList 
{ 
    ... 

其他一些類似的QA (用幾乎相同的細節)

而且我們還過濾藏品!但我們必須使用子查詢,例如Query on HasMany reference

+0

我不同意w/you, - 批次大小隻控制在提取給定項目上的當前集合時預取多少個額外集合。如果你看看我的映射,我使用延遲加載, - 無論批量大小,它只是不預取集合。如果您還注意到cirteria,我正在獲取根實體,.List (),它是根實體, - 我不明白爲什麼在select語句中有其他列(除了根實體列之外)保溼結果時不要使用。 – ActiveX

+0

'.CreateAlias(Entities.Project.PROP_PLANLIST,「p」)'是答案。這是「獲取」,實際上這是「JOIN」,它使您的* root實體*選擇乘以集合中的項目數量。我想解釋你的是:不要獲取(即不要使用'CreateAlias'' CreateCriteria''SetFetchMode')。所有這些都會使結果倍增。改爲改變你的映射。將**批量**放在每個集合映射上。最後,你會在一個SELECT中獲得平坦的根實體,並且會有更多的SQL select語句加載(懶惰)集合。現在更清楚了嗎? ;) –

+0

.CreateAlias(Entities.Project.PROP_PLANLIST,「p」),我想,這應該只改變from,where子句,但我想我錯了。我想,批量大小隻能控制預取,但現在你告訴我它也會影響select子句(我在hibernate文檔中沒有找到任何地方)?我不知道,我會盡力試試這個。請記住,我的收藏已被映射爲懶惰。我有其他的解決方案,比如嘗試SetProjection(RootEntity()),或者只使用返回Ids的子查詢返回List實例。感謝幫助。 – ActiveX

相關問題