NHibernate Criteria - 如何正确使用group by语句?

时间:2013-08-23 06:37:14

标签: c# nhibernate criteria

我有问题。我需要从数据库记录中为具有列表externalIds的ID的人员选择。之后我需要为每个人选择最新StartTime的1条记录。我尝试使用SetProjection(GroupProperty和Max属性),但结果是当我需要PersonnelPresence列表时它只返回StartTime列表。我的方法看起来像:

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>;
}

有谁知道如何解决我的问题?提前谢谢。

2 个答案:

答案 0 :(得分:0)

已经有很长一段时间了,但我仍然想尝试一点帮助。

对于这些复杂的查询,我发现首先输入SQL会有所帮助;一旦你拥有了为你提供所需结果的SQL语句,就可以更容易地将查询翻译成ICriteria。

如果可能的话,我建议使用FluentNHibernate的Query(而不是QueryOver)语法,因为这对于像你这样的复杂情况来说更容易维护和更灵活。

答案 1 :(得分: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;
}