代码之家  ›  专栏  ›  技术社区  ›  jlembke

使用Linq查询分层表/复合模式中的终端/叶节点

  •  3
  • jlembke  · 技术社区  · 16 年前

    我有一个具有Id、CategoryName和ParentId的自引用表。这是一个典型的场景,类别的层次表本身可以划分为类别,DB专家告诉我称之为邻接模型。

    我想要的是使用LINQtoSQL查询自身与其他子类别无关的子类别,即它们是某些给定类别或子类别的直接叶节点。

    最简单的部分,我得到了,就是得到了子类别。把代码放在这里几乎很尴尬。但我们确实喜欢看代码。。

    IList<Categories> subcategories = context.Where( c => c.ParentId == 1).ToList();  
    

    但是,把它缩小到没有子类别的类别,这让我大吃一惊。任何帮助都将不胜感激。

    谢谢你的帮助。 杰夫

    这似乎是可行的,但如果有人能证实这是“适当的”,我将不胜感激。因此,如果我希望叶节点位于Id=1的类别下,我会这样做:

    Categories.Where( c => !c.Children.Any ( d => d.ParentId == c.Id)).Where( e => e.ParentId == 1) 
    

    2 回复  |  直到 16 年前
        1
  •  2
  •   Pop Catalin    16 年前

    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)
    

        2
  •  0
  •   Noah    16 年前

    我想如果我正确理解了你的问题,你会试图得到所有没有子元素的子元素。。。此查询在自身上自联接表,以测试节点是否用作父节点,如果不是,则在结果中显示。

       (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()