2013-05-07 32 views
2

在像下面這樣的樹中,每個項只知道其父ID和訂單號,那麼查詢Foo所有後代的好方法是什麼?如何在linq-to-entities中有效地構建「獲取後代」算法?

  • 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總是已知的。


編輯:新增遺忘的細節,我希望它選擇所有後代,不只是孩子和孫子。

+0

即時通訊不知道我明白你的問題。你想要所有'foo'的孩子嗎? – 2013-05-07 13:26:39

+0

我想要所有foo的後代,意思是「小孩,孫子1和孫子2」,共3個項目。希望清理一些東西。各位用戶,如果不清楚,請將@JensKloster的評論投給我,我將編輯該問題。 – Nenotlep 2013-05-07 13:50:22

+0

好的。你能展示你的課程嗎? 'Foo'有'Child'的集合還是隻有一個。 「Foo」,「Child」,「GrandChild1」和「Grandchild2」是同一類型嗎? – 2013-05-07 13:54:54

回答

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); 
      } 
     } 
+0

此方法是否超出第三級?在我看來,它只會讓兒童和孫輩迴歸,但不是所有的第n級子孫都會無限地迴歸。 – Nenotlep 2013-06-13 11:02:27

+0

不,對不起,對於曾孫,這不起作用。 – 2013-08-05 21:11:54

+0

是的,我的一個要求是獲得第N級的項目,這是我的問題中的真正問題。對不起,如果不明確。我知道我可以使用遞歸方法,但我只是想避免使用所有這些拋棄的上下文(我基本上每個方法使用1個上下文)。 – Nenotlep 2013-08-29 14:17:15

1

無法找到答案,所以把我的解決方案放在這裏。我使用了一個通過調用遞歸函數來構建列表的函數。遞歸函數採用一個id,將具有該ID的行添加到列表(Descendants),檢查該行的子節點,如果有子節點,則開始一個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(); 
    } 
+0

這就是我最終做的。如果可能的話,我真的想避免遞歸,但它似乎是最簡單的選擇。 – Nenotlep 2014-02-28 08:07:38

相關問題