tags:

views:

1305

answers:

1

Is there a way of using SetMaxResult() on a sub query? Im writing a query to return all the order items belonging to the most recent order. So I need to limit the number of records on the sub query.

The equivalent sql looks something like:

SELECT i.*
FROM tbl_Orders o
JOIN tbl_OrderItems i on i.OrderId = o.Id
WHERE
o.Id in (SELECT TOP 1 o.Id FROM tbl_Orders o orderby o.Date desc)

Im using hql specifically because criteria api doesnt let you project another domain object (Im querying on orders but want to return order items)

I know that hql doesnt accept "SELECT TOP", but if I use SetMaxResult() it will apply to the outer query, not the subquery.

Any ideas?

+2  A: 

Just query the orders (and use SetMaxResult) and do a 'fetch join' to ensure all orderitems for the selected orders are loaded straight away. On the returned orders you can then access the order items without this resulting in a new SQL statement being sent to the database.

Fried Hoeben
I believe this approach should also allow you to use the criteria API, if you would prefer that.
Fried Hoeben
I was trying to avoid this route, as there is a further WHERE clause applied to the orderitems that I left out for brevity sake.So are you saying that its not possible to apply a limit on a sub query?
Andy
I don't believe it is possible to have a limit on the subquery, sorry. I fear you will need two queries (one to select the ids of the n orders that you want and then another one on the orderlines where orderId in returned list of ids). But depending on the total number of order lines for the top orders you want I would probably do more in code (i.e. fetch join all order lines for the top n orders, and then filter in code to select the order lines that you want).
Fried Hoeben
You could also take a look at filters, either on the fly (e.g. session.Filter(order.OrderLines, "where this.amount > 2")) or predefined (https://www.hibernate.org/hib_docs/nhibernate/1.2/reference/en/html/filters.html).
Fried Hoeben
Thanks Fried, splitting it into two seems to work well for what I'm doing.
Andy