2

Assuming I have:

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

I need all the hosts from a Cluster object that have a VDisk of a given name. I can do it with a foreach but would rather have a LINQ query. I tried a SelectMany() but it is returning the VDisk and not the Hosts. Do I need to implement a custom Comparer to do this?

Here's what I Tried:

Cluster CurrentCluster = new Cluster();

// add some hosts here

VDisk vdisk = new VDisk();
vdisk.Name="foo";

so now I want all the hosts that have a Vdisk named "foo"

this returns the vdisk, not the hosts:

CurrentCluster.Hosts.SelectMany(h => h.VDisks.Where(v => v.Name == vdisk.Name));
4

2 回答 2

7

SelectMany确实会返回内部集合,扁平化为一个大集合。你希望你的谓词是 on Hosts,而不是 on 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. 两者都应该做的工作,我只是更喜欢前者。

于 2013-05-30T19:30:52.050 回答
0

首先,您需要VDiskListHostas publicor中声明internal

然后你可以使用这个代码:

var hostList = new List<Host>();
var givenVDiskName = "sample name";

var selectedHosts = (from h in hostList
                     where h.VDiskList.Any(vd => vd.Name == givenVDiskName)
                     select h).ToList();
于 2013-05-30T20:31:51.963 回答