假设我有:
public class Cluster
{
List<Host> HostList = new List<Host>();
}
public class Host
{
List<VDisk> VDiskList = new List<VDisk>();
}
public class VDisk
{
public string Name {get; set}
}
我需要集群对象中具有给定名称的 VDisk 的所有主机。我可以使用 foreach 来完成,但更愿意使用 LINQ 查询。我尝试了 SelectMany() 但它返回的是 VDisk 而不是主机。我是否需要实现自定义比较器才能执行此操作?
这是我尝试过的:
Cluster CurrentCluster = new Cluster();
// add some hosts here
VDisk vdisk = new VDisk();
vdisk.Name="foo";
所以现在我想要所有具有名为“foo”的虚拟磁盘的主机
这会返回虚拟磁盘,而不是主机:
CurrentCluster.Hosts.SelectMany(h => h.VDisks.Where(v => v.Name == vdisk.Name));
最佳答案
SelectMany
确实会返回内部集合,并展平成一个大集合。您希望谓词在 Hosts
上,而不是在 VDisks
上,因为您要查找的是 Hosts
列表。
这可能有效:
CurrentCluster.Hosts.Where(h => h.VDisks.Any(v => v.Name == vdisk.Name));
它基本上是说,“返回任何 VDisk 匹配条件 v.Name == vdisk.Name
的所有主机。
我也见过不了解Any
的开发者写出这样的东西:
CurrentCluster.Hosts.Where(h => h.VDisks.Count(v => v.Name == vdisk.Name) > 0);
有时我觉得后者有一定的可读性优势,如果有人认为 Count
是一个比 Any
更直观的名称。两者都应该能胜任,我更喜欢前者。
关于c# - 如何编写更复杂的 LINQ 查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16844358/