假设我有:

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


我需要Cluster对象中具有给定名称的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);


有时候,如果有人认为CountAny更直观,我会觉得后者有一定的可读性。两者都应该做,我只是更喜欢前者。

关于c# - 如何编写更复杂的LINQ查询,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/16844358/

10-11 13:06