C# 选择许多三个层次

C# 选择许多三个层次,c#,generics,list,lambda,C#,Generics,List,Lambda,我可以使用SelectMany在集合中展平子集合的结果: // a list of Foos, a Foo contains a List of Bars var source = new List<Foo>() { ... }; var q = source.SelectMany(foo => foo.Bar) .Select(bar => bar.barId) .ToList(); 我应该如何使用SelectMany来获取我的foo列表中所有条中

我可以使用SelectMany在集合中展平子集合的结果:

 // a list of Foos, a Foo contains a List of Bars
 var source = new List<Foo>() { ... };

 var q = source.SelectMany(foo => foo.Bar)
     .Select(bar => bar.barId)
 .ToList();
我应该如何使用SelectMany来获取我的foo列表中所有条中所有小部件的列表

编辑 我错过了上面这句话的措辞,但代码反映了目标。我正在寻找所有小部件ID的列表,而不是小部件

“不正确”的结果不是所有小部件ID都返回

 var q = source.SelectMany(foo => foo.Bar)
     .SelectMany(bar => bar.Widget)
         .Select(widget => widget.WidgetId)
 .ToList();
var q = (
    from f in foo
    from b in f.Bars
    from w in b.Widgets
    select w.WidgetId
   ).ToList();

还请注意,如果您想要唯一列表,可以改为.Distinct().ToList()。

您的查询将返回所有小部件ID,而不是所有小部件。如果您只需要小部件,只需使用:

var q = source.SelectMany(foo => foo.Bar)
              .SelectMany(bar => bar.Widget)
              .ToList();
如果仍然给出“不正确的结果”,请解释错误结果的方式。示例代码将非常有用:)

编辑:好的,如果您想要小部件ID,您的原始代码应该可以:

var q = source.SelectMany(foo => foo.Bar)
              .SelectMany(bar => bar.Widget)
              .Select(widget => widget.WidgetId)
              .ToList();
这也可以写成

var q = (from foo in source
         from bar in foo.Bar
         from widget in bar.Widget
         select widgetId).ToList();
如果您喜欢查询表达式格式

这真的应该行得通——如果它不起作用,这表明你的数据有问题

我们以前应该检查过-这只是LINQtoObjects,还是更高级的提供者(例如LINQtoSQL)


我们可以调用SelectMany()的这个重载,允许我们使用lambda expression指定投影

在我看来还行。“返回的结果不正确”不是一条描述性错误消息,您得到了什么,您期望得到什么?这是假设每个Foo有一个条,每个条有一个小部件。@Jon,但这不正是他所做的吗?不。他正在每个Foo选择多个条-这就是SelectMany所做的。请参阅注释:“一个Foo包含一个条列表”。您的修改版本基本上与我的相同,只是需要两倍的代码行(如果不需要ToList(),则需要三倍的代码行)。有时查询表达式比它们的价值更麻烦:)@Jon是的,不习惯模型说foo.Bar代表1-n:(-只更新了1-n版本。是的,我的意思是说所有小部件ID,而不是返回的小部件。当我链接SelectMany(…).SelectMany(…).Select()由于某些原因,最后一次选择没有返回所有小部件ID的列表。它是对象的LINQ。好的,只要查询在我期望它如何工作方面是准确的,我就可以将问题缩小到数据并从那里开始,谢谢。在这里,我们调用三个方法,而不是四个方法
       var q = source.SelectMany(foo => foo.Bar)
          .SelectMany(bar => bar.Widget,(bar,widget) => widget.WidgetId)
          .ToList();