在NHibernate中使用JOIN选择MAX()

时间:2010-06-04 18:59:28

标签: join nhibernate group-by max having

我有一个供应商。每个供应商都有几个预订,上面有ReservationDate。

我想要一份今天预订的供应商列表。

在SQL中我会做这样的事情:

SELECT v.Id, MAX(r.ReservationDate) AS MaxDate FROM Vendor v 
INNER JOIN DailyReservation r ON v.Id = r.Vendor_Id
GROUP BY v.Id
HAVING MAX(r.ReservationDate) <> '2010-06-04'

我正在尝试在NHibernate中这样做:

session.CreateCriteria<Vendor>()
                    .CreateAlias("Reservations", "r")
                    .SetProjection(Projections.Alias(Projections.Max("r.ReservationDate"), "MaxDate"))
                    .Add(Restrictions.Not(Restrictions.Eq("MaxDate", DateTime.Today)))
                    .List<Vendor>();

这显然不起作用。我做错了什么?

编辑!我玩了更多,并且达到了这一点,这是更好的工作:

var c = Session.CreateCriteria<Vendor>();
c.CreateAlias("Reservations", "r");

ProjectionList projections = Projections.ProjectionList();
projections.Add(Projections.Max("r.ReservationDate"), "MaxDate");
projections.Add(Projections.GroupProperty("Id"));
c.SetProjection(projections);
c.Add(Restrictions.Not(Restrictions.Eq("MaxDate", DateTime.Today)));

return c.List<Vendor>();

要回答评论,我收到错误“NHibernate.QueryException:无法解析属性:MaxDate of:Vendor”

1 个答案:

答案 0 :(得分:1)

正如Mauricio所说,HQL更适合这个问题。

这是您的查询:

session.CreateQuery(
  @"
  SELECT v.Id, MAX(r.ReservationDate)
  FROM Vendor v
  JOIN v.Reservations r
  GROUP BY v.Id
  HAVING MAX(r.ReservationDate) <> :MaxDate
  ")
  .SetParameter("MaxDate", DateTime.Today)
  .List();

如您所见,它与SQL没有太大区别,除了NH已经知道关系的事实,因此您不必为Join指定字段。

但要考虑的一件事是,此查询不会返回Vendor的列表。它返回一个object[]的List,其中每一行包含两个元素:Id和MAX投影。