2010-02-22 55 views
4

鑑於下表計數:集團通過與使用NHibernate

資源:
ID INT,
名稱爲varchar(100),
地址爲varchar(500),
市VARCHAR(100) ,

ResourceViews:
ID INT,
RESOURCEID INT,
用戶id INT,
viewDate每一個資源看着,一個條目添加到該用戶的的ResourceView表時間的DateTime



下面是相應的類:

public class Resource 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public string Address { get; set; } 
    public string City { get; set; } 
    public IList<ResourceView> ResourceViews { get; set; } // simplified 
    etc. -- class simplified for question 
} 
public class ResourceView { 
    public int Id { get; set; } 
    public Resource Resource { get; set; } 
    public User User { get; set; } 
    public DateTime ViewDate { get; set; } 
} 

使用NHibernate,我如何通過類似下面的SQL檢索什麼計數獲得前5觀看次數最多的資源,以便:

SELECT * FROM [資源]
其中在(
ID從resourceViews
其中userid = 3
組由(RESOURCEID)選擇前5 RESOURCEID 爲了通過COUNT(*)遞減

獎勵積分,如果它可以與標準的API,而不是HQL來完成。

回答

5

試試這個:

DetachedCriteria dcriteria = DetachedCriteria.For<ResourceView>("rv") 
         .Add(Restrictions.Eq("userId", 3)) 
         .SetProjection(Projections.GroupProperty("rv.PostID")) 
         .AddOrder(Order.Desc(Projections.Count("rv.Id"))) 
         .SetMaxResults(5); 

var results = NHibernateSessionManager.Session.CreateCriteria<Resource>("r") 
          .Add(Subqueries.PropertyIn("r.Id", dcriteria)) 
          .List<Resource>(); 

生成的SQL看起來就像你有你的問題之一。因此,我相信這是你正在尋找的。

+0

這是近乎完美的,謝謝!獲得的積分和我把最終的解決方案作爲任何人遇到這個問題的新答案。 – 2010-02-22 13:23:11

2

tolism7了那裏的方式,99%,這裏是爲別人有類似的問題,最終的解決方案。

var dcriteria = DetachedCriteria.For<ResourceView>("rv") 
       .Add(Restrictions.Eq("User", user)) 
       .SetProjection(Projections.GroupProperty("rv.Resource")) 
       .AddOrder(Order.Desc(Projections.Count("rv.Id"))) 
       .SetMaxResults(maxResults); 
var results = Session.CreateCriteria<Resource>("r") 
       .Add(Subqueries.PropertyIn("r.Id", dcriteria)) 
       .List<Resource>(); 
2

DetachedCriteria是做的一個方法,另一種方式我認爲是更優雅是使用LINQ。

爲了幫助別人誰試圖通過這個職位和我一樣找到答案NHibernate的3.1+的問題,我會後我的問題的答案在這裏。

我使用NHibernate3.2其中完全支持LINQ是可用的。

using NHibernate.Linq;

 var session = Application.SessionFactory.GetCurrentSession(); 

     var _query = from r in session.Query<Resource>() 
        orderby r.ResourceViews.Count 
        select r; 
     return _query.Take(maxResults).ToList();