c# - 使用LINQ查询嵌套类型

Yah*_*ein 4 c# linq

我有一个如下所示的模型:

public class MyType{
 public string Id {get;set;}
 public string Name{get;set;}
 public List<MyType> Children{get;set;}
}
Run Code Online (Sandbox Code Playgroud)

在我的数据中,我只有两个级别的数据,这意味着我的对象将如下所示:

{
 MyType{"1","firstParent",
 {
  MyType{"2","firstChild",null},
  MyType{"3","secondChild",null}}
 },

 MyType{"4","secondParent",
 {
  MyType{"5","firstChild",null},
  MyType{"6","secondChild",null}}
 }
}
Run Code Online (Sandbox Code Playgroud)

如何查询MyType对象的特定Id,它可能是父或子?

以下将仅返回父母.

collection.FirstOrDefault(c => c.id==id)
Run Code Online (Sandbox Code Playgroud)

Tit*_*mir 7

您可以使用Any递归本地函数来查找任何级别的对象(您的数据结构似乎表明更深层次是可能的)

bool hasIdOrChildren(MyType t, string localId)
{
    return t.Id == localId || (t.Children != null && t.Children.Any(o => hasIdOrChildren(o, localId)));
}
collection.FirstOrDefault(c => hasIdOrChildren(c, id));
Run Code Online (Sandbox Code Playgroud)

或者使用pre C#7语法:

Func<MyType, string, bool> hasIdOrChildren = null;
hasIdOrChildren = (MyType t, string localId) =>
{
    return t.Id == localId || (t.Children != null && t.Children.Any(o => hasIdOrChildren(o, localId)));
};
collection.FirstOrDefault(c => hasIdOrChildren(c, id));
Run Code Online (Sandbox Code Playgroud)

如果您只对一个级别感兴趣,可以放弃隐遁:

collection.FirstOrDefault(c => c.Id == id || (c.Children != null && c.Children.Any(o => o.Id == id)));
Run Code Online (Sandbox Code Playgroud)

编辑

上面的代码给出了父代如果任何子代码具有id,你也可以使用SelectMany递归函数展平整个树结构:

IEnumerable<MyType> flattenTree(MyType t)
{
    if(t.Children == null)
    {
        return new[] { t };
    }
    return new[] { t }
        .Concat(t.Children.SelectMany(flattenTree));
};
collection
    .SelectMany(flattenTree)
    .FirstOrDefault(c => c.Id == id);
Run Code Online (Sandbox Code Playgroud)

此方法可用于需要展平树的任何类型的处理.

  • 这只会返回父对象吗?如果他们有正确的ID,他不想要返回子对象吗? (2认同)