子查询中的NHibernate HQL SELECT TOP

时间:2010-01-12 11:26:25

标签: nhibernate hql

有没有办法在子查询中使用SetMaxResult()?我正在编写查询以返回属于最新订单的所有订单商品。所以我需要限制子查询中的记录数。

等效的sql看起来像:

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)

我特意使用hql因为条件api不允许你投射另一个域对象(我查询订单但想要返回订单商品)

我知道hql不接受“SELECT TOP”,但如果我使用SetMaxResult(),它将应用于外部查询,而不是子查询。

有什么想法吗?

3 个答案:

答案 0 :(得分:3)

只需查询订单(并使用SetMaxResult)并执行'获取连接'即可确保所选订单的所有订单项都立即加载。 在退回的订单上,您可以访问订单项而不会导致将新的SQL语句发送到数据库。

答案 1 :(得分:3)

从NHibernate 3.2开始,您可以在查询结尾的hql中使用SKIP n / TAKE n。 您的查询将是:

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

答案 2 :(得分:1)

我也遇到过这个问题,但没有找到使用HQL的解决方案...

使用top的子查询会非常好,因为这比先完全加入要快。首先进行完全连接时,SQL Server首先连接表,然后对所有行进行排序并选择前30个。使用子选择,将获取一个表的前30列,然后与另一个表连接。这要快得多!

我使用Subselect的查询大约需要1秒,具有连接和排序的查询需要15秒!所以加入不是一种选择。

我最后得到两个查询,首先是子选择:

IQuery q1 = session.CreateQuery("select id from table1 order by id desc");
q1.SetMaxResults(100);

然后是第二个查询

IQuery q2 = session.CreateQuery("select colone, coltwo from table2 where table1id in (:subselect)");
q2.SetParameterList("subselect", q1.List());