2010-07-20 50 views
3
public class SearchText 
{ 
    public virtual int Id { get; set; } 
    public virtual string Text { get; set; } 
} 

public class SearchTextLog 
{ 
    public virtual int Id { get; set; } 
    public virtual SearchText SearchText { get; set; } 
    public virtual User User { get; set; } 
    public virtual int SearchCount { get; set; } 
    public virtual DateTime LastSearchDate { get; set; } 
} 

我試圖根據SearchTextLog中他們的計數總和選擇前5個SearchText項目。目前,我只能通過首先執行查詢來獲得前5個項目,然後在第二個查詢中使用結果來解決此問題。我想知道是否有人能告訴我光線,並教我如何將這兩個單獨的查詢集成到一個單元中。NHibernate Criteria選擇項目由組和另一個表內的itemid的總和

這是我目前有:

var topSearchCriteria = Session.CreateCriteria(typeof (SearchTextLog)) 
      .SetProjection(Projections.ProjectionList() 
          .Add(Projections.GroupProperty("SearchText.Id")) 
          .Add(Projections.Alias(Projections.Sum("SearchCount"), "SearchCount"))) 
      .AddOrder(Order.Desc("SearchCount")) 
      .SetMaxResults(topSearchLimit) 
      .List<int>(); 

return Session.CreateCriteria<SearchText>() 
      .Add(Restrictions.In("Id", topSearchCriteria.ToArray())) 
      .List<SearchText>(); 

編輯:

哦,不,我才意識到我目前的解決方案將結果失去重要訂單。所以我一定要加入這些查詢。 : -/

編輯:

我嘗試了雙向映射也允許下面的語句,但是,我不能讓它返回SEARCHTEXT項目。它只是抱怨SearchText屬性不在分組中。

return Session.CreateCriteria<SearchText>() 
       .CreateAlias("SearchTextLogs", "stl") 
       .AddOrder(Order.Desc(Projections.Sum("stl.SearchCount"))) 
       .SetMaxResults(topSearchLimit)   
       .SetResultTransformer(Transformers.AliasToEntityMap) 
       .List<SearchText>(); 

請原諒我的無知,但Nhibernate對我來說是全新的,需要一種完全不同的思維方式。

+1

檢查更新的代碼,我認爲你需要GroupProperty(生成組)以及Projections.Property告訴查詢引擎在select中生成該屬性 – Jaguar 2010-07-21 14:13:33

回答

13

好吧,我想我已經想出了一個解決方案。

根據我的問題,我原來的解決方案將無法正常工作,因爲NHibernate還不支持按屬性進行分組而不將其添加到select子句(請參閱:link text)的功能。

然而,雖然鬼混,我遇到這些很酷的事情稱爲ResultTransformers。使用AliasToBean結果轉換器,Nhibernate會自動將我給予每個投影項的別名映射到我指定的類型中的相同名稱的屬性。我簡單地指定了我的SearchText對象(但是,我必須爲sum投影項目添加一個額外的TotalSearchCount屬性)。它完美地填充了我的物體並將其返回。

return Session.CreateCriteria(typeof(SearchTextLog)) 
      .CreateAlias("SearchText", "st") 
      .SetProjection(Projections.ProjectionList() 
           .Add(Projections.Alias(Projections.GroupProperty("st.Id"), "Id")) 
           .Add(Projections.Alias(Projections.GroupProperty("st.Text"), "Text")) 
           .Add(Projections.Alias(Projections.Sum("SearchCount"), "TotalSearchCount"))) 
      .SetMaxResults(topSearchLimit) 
      .AddOrder(Order.Desc("TotalSearchCount")) 
      .SetResultTransformer(Transformers.AliasToBean(typeof(SearchText))) 
      .List<SearchText>(); 

我很驚訝,這並不容易做到。我花了大約4到5個小時的時間來研究這個問題。希望通過越來越多的經驗,我的NHibernate體驗會變得更輕鬆。

我希望這可以幫助別人!

+0

它幫助我!謝謝謝恩 – Dunc 2011-01-12 11:58:09

+0

謝謝你,幫助我呢! – MadMax1138 2012-10-05 16:21:29

1

不工作?

var critterRes = Session.CreateCriteria(typeof (SearchTextLog)) 
      .SetProjection(Projections.ProjectionList() 
          .Add(Projections.GroupProperty("SearchText")) 
          .Add(Projections.Property("SearchText")) 
          .Add(Projections.Alias(Projections.Sum("SearchCount"), "SearchCount"))) 
      .AddOrder(Order.Desc("SearchCount")) 
      .SetMaxResults(topSearchLimit) 
      .List<SearchText>() 
+0

我已經嘗試過類似的東西了。我得到以下例外: 「System.Object []」的值不是「SearchText」類型,不能在此泛型集合中使用。 – ctrlplusb 2010-07-21 08:29:04

+2

如果您調用'List ()',這*應該*工作。你沒有得到類型化對象的列表,但是如果你可以處理一個IList ,你就不必爲結果創建一個價值持有者類。儘管如此,它可能並不像接受的解決方案那樣乾淨。 – dana 2012-10-09 00:02:50

相關問題