Выберите много глубоких уровней - PullRequest
17 голосов
/ 12 марта 2009

Я могу сгладить результаты дочерней коллекции в коллекции с помощью 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. Когда я пытаюсь пройти три уровня, возвращается неправильный результат.

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

Как мне использовать SelectMany, чтобы получить список всех виджетов во всех барах в моем списке Foos?

Редактировать Я неправильно сформулировал вышеприведенное предложение, но код отражает цель. Я ищу список всех идентификаторов виджетов, а не виджетов.

«Неправильный» результат - не все идентификаторы виджета возвращаются.

Ответы [ 3 ]

32 голосов
/ 12 марта 2009

Ваш запрос возвращает все идентификаторы виджетов, а не все виджеты. Если вам нужны только виджеты, просто используйте:

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

Если это все еще дает "неправильный результат", пожалуйста, объясните, каким образом way это неправильный результат. Пример кода будет очень полезен:)

РЕДАКТИРОВАТЬ: Хорошо, если вы хотите идентификаторы виджета, ваш оригинальный код должен быть в порядке:

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)?

2 голосов
/ 12 марта 2009
var q = (
    from f in foo
    from b in f.Bars
    from w in b.Widgets
    select w.WidgetId
   ).ToList();

Также обратите внимание, что если вы хотите уникальный список, вы можете вместо этого сделать .Distinct (). ToList ().

1 голос
/ 29 января 2013
       var q = source.SelectMany(foo => foo.Bar)
          .SelectMany(bar => bar.Widget,(bar,widget) => widget.WidgetId)
          .ToList();

мы можем вызвать эту перегрузку SelectMany (), что позволяет нам определять проекцию с помощью лямбда-выражения

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...