2015-05-05 92 views
2

我知道簡單的linq,但這裏的問題語句有多層嵌套。如何爲嵌套集合編寫Linq或Lambda表達式。如何編寫嵌套集合的Linq或Lambda表達式

輸入對象定義:

public class Service 
{ 
    public string Name { get; set; } 
    public List<Service> ChildServices{ get; set; } 

    public List<Action> AvailableActions{ get; set; } 
} 

public class Action 
{ 
    public string Name { get; set; } 
    public List<string> Parameters{ get; set; } 

    public void Execute() 
    { 
     ... 
    } 
} 

嵌套可以去多層次

LINQ的期望輸出

這裏我需要寫的LINQ或Lambda表達式這

  1. 獲取所有的服務
  2. 獲得服務使用相同的名字
+0

也不關心你的輸出需要訪問集合定義的 - 除非我在這裏誤解的東西 - 在服務'從s選擇s'和'從s在服務所在s.Name = =指定的值選擇s' – jdphenix

回答

1

如果我們可以假設你開始服務的列表,像這樣:

var services = new List<Service>() 
{ 
    new Service() 
    { 
     Name = "A", 
     ChildServices = new List<Service>() 
     { 
      new Service() { Name = "C", ChildServices = new List<Service>() }, 
      new Service() 
      { 
       Name = "D", 
       ChildServices = new List<Service>() 
       { 
        new Service() { Name = "E", ChildServices = new List<Service>() }, 
        new Service() { Name = "F", ChildServices = new List<Service>() }, 
       } 
      }, 
     } 
    }, 
    new Service() 
    { 
     Name = "B", 
     ChildServices = new List<Service>() 
     { 
      new Service() { Name = "G", ChildServices = new List<Service>() }, 
      new Service() { Name = "H", ChildServices = new List<Service>() }, 
     } 
    }, 
}; 

,看起來像這樣:

services

然後這個查詢將扁平列表:

Func<IEnumerable<Service>, IEnumerable<Service>> traverse = null; 
traverse = ss => 
    from s in ss 
    from s2 in new [] { s }.Concat(traverse(s.ChildServices)) 
    select s2; 

調用traverse(services)返回此:

flattened

然後,您可以使用普通的LINQ查詢查找按名稱的服務,或者你可以做一個解釋是這樣的:

var serviceByName = traverse(services).ToDictionary(x => x.Name); 

var serviceG = serviceByName["G"]; 
0

我不認爲有直接的方式遞歸查詢嵌套集合(至少我知道)。

下面的解決方案可能適用於您的案例。

public class Service 
{ 
    public string Name { get; set; } 
    public List<Service> ChildServices{ get; set; } 

    public List<Action> AvailableActions{ get; set; } 
} 

public class Action 
{ 
    public string Name { get; set; } 
    public List<string> Parameters{ get; set; } 

    public void Execute() 
    { 

    } 
} 

public static class Extensions 
{ 
    public static IEnumerable<Service> GetAllServices(this Service node) 
    { 
     yield return node; 
     if(node.ChildServices != null) 
     { 
      foreach(var child in node.ChildServices) 
      { 
       foreach(var childOrDescendant in child.GetAllServices()) 
       { 
        yield return childOrDescendant; 
       } 
      } 
     } 
    } 
} 

工作提琴手Sample