使用NHibernate的QueryOver API嵌套集查询

时间:2013-04-16 08:33:18

标签: nhibernate queryover nested-sets

我正在使用nested sets model存储类别层次结构,也就是说,每个类别都有LeftRight值,每个类别都有更高的Left比任何父母都要小Right

我想查询属于某个类别(包括该类别)的子类别的所有类别。也就是说,我需要从给定类别开始的整个子树。

如果子树的根的id由@catId给出,我可以使用以下SQL来获取子树:

select * 
    from Category c, 
    (select [Left], [Right] from Category where Id = @catId) as t
where c.[Left] >= t.[Left] 
 and c.[Right] <= t.[Right]

现在我正在尝试使用NHibernate和QueryOver API做类似的事情。那是我有点卡住的地方。

如果我把它分成两个查询,那很简单:

var cat = session.Get<Category>(catId);

var matches = session.QueryOver<Category>()
                     .Where(x => x.Left >= cat.Left && x.Right <= cat.Right)
                     .List();

但这是两个问题 - 一个会更好。我尝试提出一个使用子查询的解决方案,虽然这在技术上有效,但查询可能不是最佳的,因为现在执行了两个子查询而不是一个。

var matches = session.QueryOver<Category>()
                     .WithSubquery.WhereProperty(x => x.Left)
                        .Ge(QueryOver.Of<Category>()
                          .Where(c => c.Id == catId)
                          .Select(c => c.Left))
                      .WithSubquery.WhereProperty(x => x.Right)
                        .Le(QueryOver.Of<Category>()
                           .Where(c => c.Id == catId)
                           .Select(c => c.Right)).List();

(除此之外,并非所有返回标量值的DBMS支持子查询,如SqlServerCE,但这是另一个问题)

有没有更好的方法来实现这一目标?如有必要,我可以为这种情况切换查询API。所以,如果e.q。在HQL中有一个简洁的方法,我很好。

1 个答案:

答案 0 :(得分:1)

我想在嵌套集中得到一个包含树的子树就像(SQL): -

SELECT 
    node.*
FROM 
    Category AS node,
    Category AS parent
WHERE 
    node.left BETWEEN parent.left AND parent.right
    AND parent.TreeID = @catID
ORDER BY 
    node.left;

这将使用在QueryOver(AFAIK)

中无法实现的CROSS JOIN

但是,HQL或更好linq都可以。