我有一个带有Id,CategoryName和ParentId的自引用表。这是类别层次表的典型场景,它们本身可以分为类别,DB专家告诉我这些类别称为邻接模型。
我想要的是使用Linq to SQL来查询本身与其他子类别无关的子类别,即它们是某个给定类别或子类别的直接叶节点。
简单的部分,我得到了,这只是获得子类别。将代码放在这里几乎不好意思。但我们确实喜欢看代码..
IList<Categories> subcategories = context.Where( c => c.ParentId == 1).ToList();
但是将它缩小到没有子类别的类别会让我感到困惑。任何帮助将不胜感激。
谢谢你的帮助。 杰夫
UPDATE ** 这似乎有效,但如果有人能证实它是“适当的”,我将不胜感激。所以,如果我想要叶子节点在Id = 1的类别下,我会这样做:
Categories.Where( c => !c.Children.Any ( d => d.ParentId == c.Id)).Where( e => e.ParentId == 1)
“Children”是Linq给出自引用关联的名称。
答案 0 :(得分:2)
您的解决方案是正确的,因为Any()
方法转换为sql“EXISTS()”函数
并且!c.Children.Any ( d => d.ParentId == c.Id))
转换为类似于NOT EXISTS (SELECT * FROM Categories WHERE ParentID = outerRef.ID)
另一种方法是使用Count
:
Categories.Where( c => c.Children.Count(d => d.ParentId == c.Id) == 0).Where( e => e.ParentId == 1)
但是通常EXISTS()优先于sql中的COUNT()(出于性能原因)所以使用Any()的解决方案应该是正确的。
答案 1 :(得分:0)
我认为如果我正确地理解了你的问题,那么你试图获得所有没有孩子的子元素...这个查询自己将表连接到自身以测试该节点是否用作父节点,如果不是那么它会显示在结果中。
我不确定这是否有效,因为我没有对它进行测试......
(from c in context
join cc in context on c.id equals cc.parentid into temp
from t in temp.DefaultIfEmpty()
where t == null
select c).ToList()