2009-03-12 3 views
16

я могу придавить результаты коллекции детской в ​​коллекции с SelectMany: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, чтобы получить список всех виджетов во всех барах в моем списке Фооса?

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

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

+0

выглядит ОК для меня. «неверный результат возвращается» не является описательным сообщением об ошибке, что вы получаете и чего вы ожидаете? – erikkallen

ответ

30

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

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

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

EDIT: Хорошо, если вы хотите виджет идентификаторы, исходный код должен быть хорошо:

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 для объектов или поставщик фанов (например, LINQ to SQL)?

+1

Да, я хотел сказать все идентификаторы виджетов, а не возвращенные виджеты. Когда я цепляю SelectMany (...). SelectMany (...). Выберите() последний выбор не возвращает список всех идентификаторов виджетов по какой-либо причине. – blu

+0

Его LINQ-to-Objects. Хорошо, пока запрос является точным с точки зрения того, как я ожидаю, что он будет работать, я могу сузить проблему до данных и перейти оттуда, спасибо. – blu

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

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

+0

Это предполагает наличие одного бара за Foo и одного виджета на баре. –

+0

@ Джон, но разве это не то, что он делает? – eglasius

+0

Нет. Он выбирает несколько баров на Foo - это то, что делает SelectMany. –

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

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

+0

здесь мы вызываем три метода вместо четырех –

Смежные вопросы