我正在使用nested sets model存储类别层次结构,也就是说,每个类别都有Left
和Right
值,每个类别都有更高的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中有一个简洁的方法,我很好。