选择多个三个层次

时间:2009-03-12 20:48:10

标签: 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();

这给了我Foo列表中所有Bar ID的列表。当我尝试深入三级时,会返回错误的结果。

 var q = source.SelectMany(foo => foo.Bar)
     .SelectMany(bar => bar.Widget)
         .Select(widget => widget.WidgetId)
 .ToList();

我应该如何使用SelectMany获取Foos列表中所有条形图中所有小部件的列表?

修改 我错过了上面的句子,但代码反映了目标。我正在寻找所有Widget ID的列表,而不是小部件。

“不正确”的结果并非返回所有小部件ID。

3 个答案:

答案 0 :(得分:32)

您的查询返回所有窗口小部件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();

如果你喜欢查询表达格式。

这确实应该有效 - 如果它正在工作,那表明你的数据有问题。

我们之前应该检查过 - 这只是LINQ to Objects,还是一个更高级的提供者(例如LINQ to SQL)?

答案 1 :(得分:2)

var q = (
    from f in foo
    from b in f.Bars
    from w in b.Widgets
    select w.WidgetId
   ).ToList();

另请注意,如果您需要唯一列表,则可以执行.Distinct()。ToList()。

答案 2 :(得分:1)

       var q = source.SelectMany(foo => foo.Bar)
          .SelectMany(bar => bar.Widget,(bar,widget) => widget.WidgetId)
          .ToList();

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