2012-09-07 16 views
6

Ho una domanda per voi esperti di linq là fuori! In un elenco annidato di istanze di Component, ho bisogno di sapere se c'è un componente di un particolare tipo in esso. Può essere espresso da linq? Tieni presente che potrebbero esserci application.Components [0] .Components [0] .Components [0] ... La mia domanda è orientata alle query ricorsive in linq!elenco nidificato linq contiene

Vi lascio le entità per voi per avere qualche idea del modello.

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 
} 

risposta

5

Volete sapere se uno dei componenti in un componente è di un certo tipo?

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

che dire innercomp.components?

Edit: Così si vuole trovare i componenti di un dato tipo in modo ricorsivo, non solo sul piano superiore o secondo. Quindi è possibile utilizzare il metodo seguente Traverse estensione:

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; 
      } 
     } 
    } 
} 

per essere utilizzato in questo modo: i dati

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

campione:

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

che dire di innercomp.components? –

+0

@IrrationalRationalWorks: Modificato la mia risposta. –

+0

Sto mangiando arcobaleni ... Fammi controllare –

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

o si può fare

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

che dire c.components? –