2

在像下面这样的树中,每个项目只知道它的父 ID 和订单号,那么查询 Foo 的所有后代的好方法是什么?

  • 1:富
    • 2:儿童
      • 3:孙子 1
      • 4:孙子2
  • 5:酒吧
  • 6:巴兹

我可以得到这样的孩子

var q = from item in foos
        where item.parentid == "Foo"
        select item;

但是我怎样才能在一个查询中让所有后代达到任何深度呢?如果可能,我想避免使用多个查询进行递归。具体来说,我想获得所有可能级别的后代,不仅是子孙,还包括第 n 级子孙。我想我可以使用这种情况下的订单号和类似的查询

var q = from item in foos
        where item.ordernumber > 1 && item.ordernumber < 5
        select item;

但在这种情况下,我无法弄清楚如何获得5,这意味着下一个非后代订单号。在这1一点上总是已知的。


编辑:添加了被遗忘的细节,我希望它选择所有后代,而不仅仅是孩子和孙子孙女。

4

2 回答 2

1

无法找到答案,所以将我的解决方案放在这里。我使用了一个通过调用递归函数来构建列表的函数。递归函数接受一个 id,将具有该 ID 的行添加到列表(后代),检查该行的子代,如果有子代,则它启动一个 foreach 并为每个子代调用自身,传入子代的 id :

    public List<WikiPageModel> Descendants;        

    public List<WikiPageModel> GetDescendantsOf(int id)
    {
        Descendants = new List<WikiPageModel>();
        GetDescendantsOf_Recursor(id);
        return Descendants;
    }

    public void GetDescendantsOf_Recursor(int id)
    {
        var page = WikiPages.FirstOrDefault(x => x.PageId == id);
        Descendants.Add(page);
        var children = GetChildrenOf(id);
        if (children.Any())
        {
            foreach (var child in children)
            {
                id = child.PageId;
                GetDescendantsOf_Recursor(id);
            }
        }
    }

    public List<WikiPageModel> GetChildrenOf(int pageId)
    {
        return WikiPages.Where(x => x.ParentPageId == pageId).ToList();
    }
于 2014-02-27T08:20:56.683 回答
0
public class Element
    {
        public int ID { set; get; }
        public string Name { get; set; }
        public List<Element> Children { get; set; }
    }

static void Main(string[] args)
        {
            List<Element> elements = new List<Element>();
            Element Foo = new Element() { ID = 1, Name = "Foo" };
            Element Child = new Element() { ID = 2, Name = "Child" };
            Element GrandChild1 = new Element() { ID = 3, Name = "GrandChild 1" };
            Element GrandChild2 = new Element() { ID = 4, Name = "GrandChild 2" };
            Element Bar = new Element() { ID = 5, Name = "Bar" };
            Element Baz = new Element() { ID = 6, Name = "Baz" };
            Foo.Children = new List<Element>();
            Foo.Children.Add(Child);
            Child.Children = new List<Element>();
            Child.Children.Add(GrandChild1);
            Child.Children.Add(GrandChild2);
            elements.Add(Foo);
            elements.Add(Bar);
            elements.Add(Baz);
            var query = elements.Where(e => e.Name == "Foo").SelectMany(c => c.Children);
            var query2 = query.Union(query.SelectMany(g => g.Children));

            foreach (var item in query2)
            {
                Console.WriteLine(item.Name);
            }
        }
于 2013-05-07T20:36:38.513 回答