2013-05-15 97 views
0

當有一個域模型集合在一個集合中並且渴望獲取相同的集合時,我經常聽到來自我的同事的「Cartesian Product」一詞。假設我有下面的模型。NHibernate中的笛卡爾積是什麼?

public class Order{ 
    List<Product> Products 
} 
public class Product{ 
    List<Units> Units 
} 

現在他們說,如果我試圖預先抓取的產品和單位訂購,我應該得到一個笛卡爾積(又名重複..)。 但是,當我通過啓用ShowSql來測試它時,我似乎沒有得到任何重複。 這是我的倉庫類

public List<Order> GetOrdersWithProductsAndUnits() 
    { 
     return GetSession().Query<Order>() 
          .FetchMany(order => order.Products) 
          .ThenFetch(product => product.Units) 
          .ToList(); 
    } 

而這裏的扶持ShowSql的SQL輸出。這看起來很好,並且如所期望的那樣在必要的表上加入。

select order0_.Id as Id8_0_, 
childstock1_.Id as Id23_1_, 
childstock2_.Id as Id24_2_, 
order0_.CustomerName as Customer2_8_0_, 
order0_.City as City8_0_, 
childstock1_.Size as Size23_1_, 
childstock2_.Box as Box24_2_, 
from Orders order0_ 
left outer join Products childstock1_ on order0_.Id=childstock1_.OrderId 
left outer join Units childstock2_ on childstock1_.Id=childstock2_.ProductId 

我有125臺的訂單在我的數據庫,並與產品和單位時,我渴望獲取訂單我仍然得到125條記錄。

List<Order> orders = repository.GetOrdersWithProductsAndUnits(); 
    Assert.That(orders.Count,Is.EqualTo(125)); 

此外,當我通過Visual Studio調試器檢查時,我發現產品或單位級別的Order Collection內沒有任何重複。

由於笛卡爾產品導致重複,我期待在我的數據庫中有多少Orders作爲單位(接近1000)。我錯過了一些微不足道的東西,我對笛卡爾產品的理解是否有偏差?或者,我正在使用的查詢API會自動自動解決笛卡爾產品問題。

僅供參考:我確信數據設置也是如此。我已經通過Visual Studio Debugger進行了調試,並且我注意到具有多個產品和多個產品的訂單。

讚賞任何幫助/參考資料。

由於

+0

你確定數據是按照你說的方式設置的嗎?訂單是否有與其相關的任何產品? –

+0

是的,我很確定,我通過Visual Studio調試窗口進行了調試。每個訂單都有很多產品,每個產品都有很多單位。 –

+0

好吧 - 另一件事是,NHibernate協調「額外」記錄 - 你是否嘗試過直接運行SQL並查看結果?另外,我不認爲這可能會導致笛卡爾產品。從技術上講,這將加入每一個訂單,反對每一個產品對每個單位。如果沒有交叉連接,我不認爲這是可能的,但我可能是錯的。 –

回答

0

與其他查詢類型(HQL,條件,QueryOver)NHibernate的自動丟棄在LINQ查詢重複根實體。但正如你在上次評論中所說的,你仍然從數據庫中獲得很多行,所以你的查詢可能會很慢。

+0

yup,你說得對。事實證明,NHibernate的LINQ API自動在結果集上執行DistinctRootEntityResultTransformer。因此..我只得到不同的Order Ids,但是,在那些訂單中,我確實發現了重複的產品(與產品數量一樣多)。 –

0

使用像HibernatingRhinos這樣的東西將幫助你非常。我已經使用他們的EF工具,並避免了笛卡爾產品的許多問題,我不知道其他情況發生了。 ORM創建笛卡爾產品的主要罪魁禍首通常是加載/深層讀取對象樹。使用基於視圖的模型對象可以輕鬆避免它,而不是通過在代碼中將對象鏈接在一起來構建結果集。