I can flatten the results of a child collection within a collection with 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();
this gives me the list of all Bar Ids in the Foo List. When I attempt to go three levels deep the incorrect result is returned.
var q = source.SelectMany(foo => foo.Bar) .SelectMany(bar => bar.Widget) .Select(widget => widget.WidgetId) .ToList();
How should I be using SelectMany to get the list of all Widgets in all Bars in my list of Foos?
Edit I miss-worded the above sentence, but the code reflects the goal. I am looking for a list of all Widget Ids, not widgets.
An "incorrect" result is not all of the widget ids are returned.
Your query is returning all the widget IDs, instead of all the widgets. If you just want widgets, just use:
var q = source.SelectMany(foo => foo.Bar) .SelectMany(bar => bar.Widget) .ToList();
If that's still giving "the incorrect result" please explain in what way it's the incorrect result. Sample code would be very helpful :)
EDIT: Okay, if you want the widget IDs, your original code should be fine:
var q = source.SelectMany(foo => foo.Bar) .SelectMany(bar => bar.Widget) .Select(widget => widget.WidgetId) .ToList();
That could also be written as
var q = (from foo in source from bar in foo.Bar from widget in bar.Widget select widgetId).ToList();
if you like query expression format.
This really should work - if it's not working, that suggests there's something wrong with your data.
We should have checked before - is this just LINQ to Objects, or a fancier provider (e.g. LINQ to SQL)?
var q = ( from f in foo from b in f.Bars from w in b.Widgets select w.WidgetId ).ToList();
Also note that if you want the unique list, you can do .Distinct().ToList() instead.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With