注意:由于机密性,我已更改了收藏品的名称。
请考虑以下代码:
o.Flag =
o2.Collection1
.Any(cpd => cpd.Collection1
.Any(plc => plc.Collection1
.Any(vd => vd.DetailedFlag))) ||
o2.Collection1
.Any(cpd => cpd.Collection2
.Any(plc => plc.Collection1
.Any(vd => vd.DetailedFlag)));
显然我正在做的是将详细的标志扁平化为整体标志,但这段代码将迭代o2.Collection1
两次。
我不知道SelectMany
如何能够完成这项工作,因为这些标志位于两个不同的集合上(即我没有展开集合的集合)。
我怎样才能避免这样做?
注意:我觉得Jon Skeet,当我看到这篇文章(Using LINQ to flatten a hierarchical dataset - with a caveat)基本上是说我被卡住了。但希望我读错了!
答案 0 :(得分:6)
如果集合属于同一类型(或者具有定义足够信息的公共基本类型),您可以在查询中简单地连接它们:
o.Flag =
o2.Collection1
.Any(cpd => cpd.Collection1.Concat(cpd.Collection2)
.Any(plc => plc.Collection1
.Any(vd => vd.DetailedFlag)));
请注意,这里的主要优点是简单地进行查询,并减少代码重复。它对其执行效果不会产生任何明显影响as long as your collection is actually an in memory collection
如果它们不是兼容类型(或者每个子集合的谓词存在细微差别,与给出的示例不同),那么您可以管理的最好的是将两个子查询都拉入到谓词中。主要收藏:
o.Flag =
o2.Collection1
.Any(cpd => cpd.Collection1
.Any(plc => plc.Collection1
.Any(vd => vd.DetailedFlag)) ||
cpd.Collection2
.Any(plc => plc.Collection1
.Any(vd => vd.DetailedFlag)));
答案 1 :(得分:4)
您可以使用单次迭代直到第一层,然后分支到两个单独的查询。
o.Flag =
o2.Collection1
.Any(cpd => cpd.Collection1
.Any(plc => plc.Collection1
.Any(vd => vd.DetailedFlag)) ||
cpd.Collection2
.Any(plc => plc.Collection1
.Any(vd => vd.DetailedFlag)));