LINQ嵌套列表包含

6

我有一个问题想问问各位linq专家!在一个嵌套的组件实例列表中,我需要知道是否存在特定类型的组件。这能用linq表达吗?请注意,可能会有application.Components [0] .Components [0] .Components [0]...我的问题是针对linq中递归查询的。

我把实体留给你们,让你们对模型有一些了解。

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
}
2个回答

5
你想知道一个组件中是否存在给定类型的组件吗?
var webType = ComponentType.WebApplication;
IEnumerable<Component> webApps = from c in components
                                 from innerComp in c.Components
                                 where innerComp.Type == webType;
bool anyWebApp = webApps.Any();

innercomp.components 怎么样?

编辑: 所以你想递归地查找给定类型的组件,而不仅仅是在顶层或第二层。那么你可以使用以下的Traverse扩展方法:

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

应该以这种方式使用:

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

示例数据:

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

内部组件 innercomp.components 怎么样? - Irrational RationalWorks
我正在吃彩虹... 让我检查一下。 - Irrational RationalWorks
1
你是极致的Linq、扩展方法和递归大师Tim! - Irrational RationalWorks

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

或者你可以这样做

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接