c# - 如何编写更复杂的 LINQ 查询

标签 c# linq

假设我有:

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/

相关文章:

c# - 关于参数、参数和类型如何工作的说明

c# - 用于比较的订单日期列表

mysql - ASP.NET MVC 应用程序的数据库和逻辑层

linq - 我将如何在 Linq 中执行带合并的左连接?

c# - Entity Framework (.NET 完整框架)订购包括

c# - 如何确保 List<String> 只包含序列中的每个字符串一次

c# - 如何使用 ValueInjecter 根据扁平化属性的名称查找源属性

c# - IIS 部署的 ASP.NET Core 应用程序提供间歇性 431 请求 header 太长错误

c# - 从ViewModel访问数据库是否违反了MVC原则?

c# - 限制 MSMQ 消息/优先处理消息