4

我有问题。我需要从数据库记录中选择具有列表 externalIds 中 id 的人员。之后,我只需要为每个人选择 1 条具有最新 StartTime 的记录。例如,我尝试使用 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>;
}

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

4

2 回答 2

0

已经很久了,但我仍然想尝试并提供一些帮助。

对于诸如此类的复杂查询,我发现先键入 SQL 会有所帮助;一旦您有了能够提供所需结果的 SQL 语句,就更容易将查询转换为 ICriteria。

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

于 2015-04-14T08:47:21.837 回答
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;
}
于 2015-08-11T21:44:57.730 回答