2010-02-22 4 views
4

Учитывая следующие таблицы:Группировка с графом, используя NHibernate

Ресурсы:
ID ИНТ
Name VARCHAR (100),
Адрес VARCHAR (500),
Город VARCHAR (100) ,
т.д.

ResourceViews:
Id ИНТ
RESOURCEID INT,
идентификатор пользователя INT,
viewDate DateTime

каждый раз, когда ресурс смотрел, добавляется запись в таблицу ResourceView для этого пользователя.

Вот соответствующие классы:

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, как я могу получить топ-5 самых просматриваемых ресурсов в порядке подсчета аналогично тому, что получает следующий SQL:

выберите * из [ресурс]
, где идентификатор (
выбрать лучшие 5 ResourceId от resourceViews
, где идентификатор пользователя = 3
группы путем (ResourceId)
порядок по количеству (*) по алфавиту
)

бонусных очков, если это может быть сделано с Criteria 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

Это было почти идеально, спасибо !! Полученные очки и я поставил окончательное решение в качестве нового ответа для всех, кто сталкивался с этим вопросом. –

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(); 
Смежные вопросы