2008-11-25 131 views
28

我試圖在NHibernate中使用Criteria API獲得不同的結果。我知道這可以使用HQL,但我更願意使用Criteria API來做到這一點,因爲我的應用程序的其餘部分僅使用此方法編寫。我found this forum post,但一直未能得到它的工作。使用標準API獲取不同的結果集有什麼方法嗎?使用Criteria API從NHibernate獲取不同的結果集?

編輯:在這樣做時,我也想排除主鍵列,這也是一個身份,並獲得其餘的不同的記錄。有沒有辦法做到這一點?事實上,不同的記錄會返回重複項,因爲主鍵對於每一行都是唯一的,但所有其他字段都是相同的。

回答

23

無法看到論壇的帖子在這一刻,也許這是不是答案,但你可以添加一個DistinctRootEntityResultTransformer(斷鏈):

session.CreateCriteria(typeof(Product) 
    .Add(...) 
    .SetResultTransformer(new DistinctEntityRootTransformer()) 
+0

好吧,我從來沒有這樣做過,所以1快速的問題。我有一個主鍵,這是一個身份字段。我怎樣才能從結果集中排除這個字段,以便不同的結果真的不同?我可以澄清,如果沒有意義。 – 2008-11-25 19:20:35

+0

我不知道這是否可能。你可以創建一個與其他字段的DTO,並針對該DTO進行查詢,但它需要使用hql。 – Juanma 2008-11-26 10:40:01

+0

DistinctEntityRootTransformer來自哪裏? VS不會爲我解決它。我在某處丟失了一個程序集嗎? – BuddyJoe 2009-02-18 21:34:12

86

要執行不同的查詢,您可以設置投影關於Projections.Distinct的標準。然後包括您想要返回的列。然後通過將結果轉換器設置爲AliasToBeanResultTransformer - 將結果轉換成的類型傳入,然後將結果轉回爲強類型對象。在這個例子中,我使用與實體本身相同的類型,但是您可以專門爲此查詢創建另一個類。

ICriteria criteria = session.CreateCriteria(typeof(Person)); 
criteria.SetProjection(
    Projections.Distinct(Projections.ProjectionList() 
     .Add(Projections.Alias(Projections.Property("FirstName"), "FirstName")) 
     .Add(Projections.Alias(Projections.Property("LastName"), "LastName")))); 

criteria.SetResultTransformer(
    new NHibernate.Transform.AliasToBeanResultTransformer(typeof(Person))); 

IList<Person> people = criteria.List<Person>(); 

這(至少在SQL Server)創建類似於SQL:

SELECT DISTINCT FirstName, LastName from Person 

請注意,只有您在投影中指定的屬性將在結果來填充。

此方法的優點是過濾在數據庫中執行,而不是將所有結果返回到您的應用程序,然後執行過濾 - 這是DistinctRootEntityTransformer的行爲。

-4

我也遇到了非明顯數量的項目的問題(我在我的映射文件中使用fetch =「join」)。我使用LINQ的NHibernate的要解決的問題,這是在使用方式如下:

 var suppliers = (from supplier in session.Linq<Supplier>() 
         from product in supplier.Products 
         where product.Category.Name == produtCategoryName 
         select supplier).ToList().Distinct(); 
-1

我們將使用所有的最先進,最強大和令人印象深刻的小手段來處理這個問題......只有當你閱讀「再爲真棒準備......它有沒有關係準則...

CurrentSession() 
    .QueryOver<GoodBadAndUgly> 
    .Where(...) 
    .TransformUsing(Transformers.DistinctRootEntity) 

所以,如果你來這裏希望有辦法做到這一點,有你避免與標準甚至搞亂雖然你雖然你將完全不得不朝着這個方向去添加'DISTINCT'到你的SQL中...不再搜索