SELECT MAX () avec joignons à Hibernate
-
24-10-2019 - |
Question
J'ai un fournisseur. Chaque fournisseur a plusieurs réservations, avec un ReservationDate dessus.
Je veux une liste des fournisseurs qui ont pas fait une réservation encore aujourd'hui.
Dans SQL je ferais quelque chose comme ceci:
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'
Je suis en train le faire dans NHibernate comme ceci:
session.CreateCriteria<Vendor>()
.CreateAlias("Reservations", "r")
.SetProjection(Projections.Alias(Projections.Max("r.ReservationDate"), "MaxDate"))
.Add(Restrictions.Not(Restrictions.Eq("MaxDate", DateTime.Today)))
.List<Vendor>();
ne fonctionne manifestement pas. Qu'est-ce que je fais mal?
!EDIT J'ai joué un peu plus, et a obtenu à ce point, ce qui fonctionne mieux:
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>();
Et pour répondre à ce commentaire, je reçois l'erreur « NHibernate.QueryException: ne pouvait pas résoudre la propriété: MaxDate de: Fournisseur »
La solution
Mauricio mentionné, HQL est un meilleur ajustement à ce problème.
Voici votre requête:
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();
Comme vous le voyez, il n'y a pas beaucoup différent de SQL, à l'exception du fait que NH connaît déjà les relations, de sorte que vous ne devez pas spécifier le champ pour la jointure.
Une chose à considérer, cependant, est que cette requête ne renvoie pas une liste de Vendor
. Il renvoie une liste de object[]
, où chaque ligne contient deux éléments:. L'ID et la projection MAX