2012-09-07 12 views
6

¡Tengo una pregunta para usted expertos de linq allí! En una lista anidada de instancias de componente, necesito saber si hay un componente de un tipo particular en él. ¿Puede ser expresado por linq? Tenga en cuenta que puede haber aplicación.Componentes [0] .Componentes [0] .Componentes [0] ... Mi pregunta está orientada a consultas recursivas en linq!lista anidada de linq contiene

Te dejo las entidades para que tengas una idea del modelo.

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 
} 

Respuesta

5

¿Quieres saber si alguno de los componentes de un componente es de un tipo dado?

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

¿qué pasa con innercomp.components?

Editar: Así que usted quiere encontrar los componentes de un tipo dado recursiva no sólo en el nivel superior o segundo. A continuación, puede utilizar el método siguiente Traverse extensión:

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

para ser utilizado de esta manera: los datos

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

muestra:

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

¿qué pasa con innercomp.components? –

+0

@IrationalRationalWorks: Editado mi respuesta. –

+0

Estoy comiendo arcoiris ... Déjame revisar –

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

o puede hacerlo

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

¿qué pasa con c.components? –