2012-09-07 25 views
6

Mam dla ciebie pytanie do ekspertów Linq! Na zagnieżdżonej liście wystąpień komponentów muszę się dowiedzieć, czy zawiera komponent określonego typu. Czy można to wyrazić linq? Weź pod uwagę, że może istnieć application.Components [0] .Components [0] .Components [0] ... Moje pytanie jest zorientowane na zapytania rekursywne w linq!zagnieżdżona lista linq zawiera

Zostawiam wam byty, abyście mieli pojęcie o modelu.

public class Application 
{ 
    public List<Component> Components { get; set; } 
} 

public class Component 
{ 
    public ComponentType Type { get; set; } 
    public List<Component> Components { get; set; } 
} 

public enum ComponentType 
{ 
    WindowsService, 
    WebApplication, 
    WebService, 
    ComponentGroup 
} 

Odpowiedz

5

Chcesz wiedzieć, jeśli którykolwiek ze składników składnika jest danego typu?

var webType = ComponentType.WebApplication; 
IEnumerable<Component> webApps = from c in components 
           from innerComp in c.Components 
           where innerComp.Type == webType; 
bool anyWebApp = webApps.Any(); 

co innercomp.components?

Edit: Więc chcesz znaleźć elementy danego typu rekurencyjnie nie tylko na górze lub drugiego poziomu. Następnie można użyć następującej metody Traverse rozszerzenia:

public static IEnumerable<T> Traverse<T>(this IEnumerable<T> source, Func<T, IEnumerable<T>> fnRecurse) 
{ 
    foreach (T item in source) 
    { 
     yield return item; 

     IEnumerable<T> seqRecurse = fnRecurse(item); 
     if (seqRecurse != null) 
     { 
      foreach (T itemRecurse in Traverse(seqRecurse, fnRecurse)) 
      { 
       yield return itemRecurse; 
      } 
     } 
    } 
} 

być używane w ten sposób: dane

var webType = ComponentType.WebApplication; 
IEnumerable<Component> webApps = components.Traverse(c => c.Components) 
           .Where(c => c.Type == webType); 
bool anyWebApp = webApps.Any(); 

próbkowania:

var components = new List<Component>() { 
    new Component(){ Type=ComponentType.WebService,Components=null }, 
    new Component(){ Type=ComponentType.WebService,Components=new List<Component>(){ 
     new Component(){ Type=ComponentType.WebService,Components=null }, 
     new Component(){ Type=ComponentType.ComponentGroup,Components=null }, 
     new Component(){ Type=ComponentType.WindowsService,Components=null }, 
    } }, 
    new Component(){ Type=ComponentType.WebService,Components=null }, 
    new Component(){ Type=ComponentType.WebService,Components=new List<Component>(){ 
     new Component(){ Type=ComponentType.WebService,Components=new List<Component>(){ 
      new Component(){Type=ComponentType.WebApplication,Components=null} 
     } }, 
     new Component(){ Type=ComponentType.WindowsService,Components=null }, 
     new Component(){ Type=ComponentType.WebService,Components=null }, 
    } }, 
    new Component(){ Type=ComponentType.WebService,Components=null }, 
    new Component(){ Type=ComponentType.ComponentGroup,Components=null }, 
    new Component(){ Type=ComponentType.WebService,Components=null }, 
}; 
+0

co z wewnętrznymi komponentami? –

+0

@IrrationalRationalWorks: Edytowałem moją odpowiedź. –

+0

Ja jem tęcze ... Pozwól mi sprawdzić –

1
if(Components.Any(c => c.Type == ComponentType.WindowsService)) 
{ 
    // do something 
} 

czy można zrobić

var listContainsAtLeastOneService = 
    (from c in Components 
     where c.Type == ComponentType.WindowsService 
     select c).Any(); 
+0

co o c.components? –