2009-03-12 17 views
16

私はSelectManyで、コレクション内の子コレクションの結果を平らにすることができますSelectMany 3つのレベルディープ

// 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リスト内のすべてのバーIDのリストを提供します。私は3つのレベル深く行くと、間違った結果が返されます。

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

どのように私は、FOOSの私のリストにあるすべてのバーにあるすべてのウィジェットの一覧を取得するにはSelectManyを使用すべきですか?

上記の文が間違っていますが、コードには目標が反映されています。ウィジェットではなく、すべてのウィジェットIDのリストを探しています。

"間違った"結果がすべてのウィジェットIDが返されるわけではありません。

+0

は私にOK見えるラムダexperessionを使用して投影を指定できるようにするとSelectManyのこのオーバーロード()を呼び出すことができます。 "間違った結果が返されます"という記述的なエラーメッセージではありません。何を得るのですか?何を期待していますか? – erikkallen

答えて

30

クエリは、すべてのウィジェットではなく、すべてのウィジェットIDを返しています。あなただけのウィジェットをしたい場合は、単に使用:

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

をそれはまだ「間違った結果を」与えている場合、それは誤った結果だ何方法で説明してください。サンプルコードは、非常に参考になる:)

EDIT:あなたがウィジェットのIDをしたい場合さて、あなたの元のコードは問題ないはずです。

var q = (from foo in source 
     from bar in foo.Bar 
     from widget in bar.Widget 
     select widgetId).ToList(); 

のように書くことができ

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

あなたがクエリ表現形式を好きなら。

これは実際にはうまくいくはずです。でない場合は、のデータが表示されます。

これは、LINQ to Objects、または魅力的なプロバイダ(LINQ to SQLなど)です。

+1

ええ、私はすべてのウィジェットID、ウィジェットは返されません。 SelectMany(...)。SelectMany(...)。Select()最後の選択が何らかの理由ですべてのウィジェットIDのリストを返しません。 – 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ごとに1つのBar、1つのBarごとに1つのWidgetを前提としています。 –

+0

@ジョンしかし、彼が何をしているのか正確には分からないのですか? – eglasius

+0

いいえ、彼はFooごとに複数のバーを選択しています - それはSelectManyの機能です。 –

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

私たちは私たちが

+0

ここでは、4つではなく3つのメソッドを呼び出すことになります –

関連する問題