2010-02-22 72 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();