2010-06-04 62 views
1

我有一个供应商。每个供应商都有几个预订,其中有一个预订日期。选择MAX()加入NHibernate

我想要一个供应商列表而不是今天进行了预订。

在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的:供应商“

+0

你得到的错误是什么? – 2010-06-04 19:01:23

+0

您使用Criteria而不是HQL的任何特定原因? – 2010-06-04 19:11:28

+0

@Jon,我编辑了这个问题。 @Mauricio,不是真的。我没有使用HQL,所以我只是用我所知道的(略好一点)。 – 2010-06-04 19:17:32

回答

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已经知道了那个关系的事实,所以你不必指定字段加入。

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

+0

谢谢迭戈! HQL取得了诀窍。 – 2010-06-07 15:03:55