2013-08-23 2 views
4

У меня проблемы. Мне нужно выбрать из записей базы данных для людей с идентификаторами, которые находятся в списке externalIds. После этого мне нужно выбрать для каждого человека только 1 запись с новейшим StartTime. Я попытался, например, с SetProjection (свойство GroupProperty и Max), но в результате он возвращает мне только список StartTime, когда мне нужен список PersonnelPresence. Мой метод выглядит так:Критерии NHibernate - как правильно использовать группу по заявлению?

public IList<PersonnelPresence> GetLastPersonnelPresencesForPeopleExternalIds(IList<string> externalIds) 
{ 
      ICriteria criteria = Session.CreateCriteria(typeof(PersonnelPresence), "pp").CreateCriteria("pp.Person", "p") 
       .Add(Restrictions.In("p.ExternalId", externalIds.ToList())) 
       .SetProjection(Projections.ProjectionList() 
       .Add(Projections.GroupProperty("p.Id")) 
       .Add(Projections.Max("pp.StartTime"))); 

      return criteria.List<Object>() as List<PersonnelPresence>; 
} 

Кто-нибудь знает, как решить мою проблему? Заранее спасибо.

ответ

0

Прошло много времени, но все же я хотел бы попробовать немного помочь.

С такими сложными запросами, я нахожу, что он помогает сначала набирать SQL; если у вас есть оператор SQL, который дает вам нужные результаты, проще перевести запрос в ICriteria.

Если возможно, я рекомендую использовать синтаксис Query (not QueryOver) FluentNHibernate, поскольку это намного проще в обслуживании и более гибко в сложных случаях, таких как ваши.

0

У меня была аналогичная проблема, поэтому, если кто-то захочет чего-то подобного, мне удалось решить, разделив запрос на два.

Нечто подобное:

public IList<PersonnelPresence> GetLastPersonnelPresencesForPeopleExternalIds(IList<string> externalIds) 
{ 
    var criteriaPersonnelPresenceNewest = DetachedCriteria.For<PersonnelPresence>("PP_") 
               .Add(Restrictions.In("PP_.ExternalId", externalIds.ToArray()())) 
               .Add(Restrictions.EqProperty("PP_.ExternalId", "PP2_.ExternalId"))//to compare with the query down below 
               .SetProjection(Projections.ProjectionList() 
                      .Add(Projections.Max("PP_.StartTime")) 
               ); 

var criteriaPersonnelPresence = Session.CreateCriteria<PersonnelPresence>("PP2_")             
             .Add(Subqueries.PropertyEq("PP2_.StartTime", criteriaPersonnelPresenceNewest)) 
             .SetProjection(Projections.ProjectionList() 
                    .Add(Projections.Property("PP2_.Id")) 
                    .Add(Projections.Property("PP2_.StartTime")) 
             ) 
             .ToList<PersonnelPresence>(); 

return criteriaPersonnelPresence; 
} 
Смежные вопросы