2015-05-05 65 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