linq nested list contains

柔情痞子 提交于 2019-12-07 03:49:29

问题


I have a question for you linq experts out there! In a nested list of Component instances, I need to know if there is a component of a particular type in it. Can it be expressed by linq? Take into account that there may be application.Components[0].Components[0].Components[0]... My question is oriented to recursive queries in linq!

I leave you the entities for you to have some idea of the model.

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
}

回答1:


You want to know if any of the components in a component is of a given type?

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

what about innercomp.components?

Edit: So you want to find components of a given type recursively not only on the top or second level. Then you can use following Traverse extension method:

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

to be used in this way:

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

sample data:

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



回答2:


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

or you can do

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


来源:https://stackoverflow.com/questions/12318372/linq-nested-list-contains

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!