2011-11-10 9 views
1

を使用してLINQ GROUPBY選択にプロパティを設定しようとしています。私がしようとした場合でも:は、私は次のコードを持っているループ

foreach (var item in result) 
{ 
    item.Sales = 50; 
} 

をしかし、私は次のコードを使用してプロパティを設定した場合、それは動作します:

var result = myItems.GroupBy(x => new { Id = x.Id, Name = x.Name }).Select(x => new Report { Id = x.Key.Id, Name = x.Key.Name, Sales = 50 }); 

は、設計によって、このですか?

答えて

5

問題は、LINQクエリが遅延(「遅延実行」)していることです。 はループでクエリの各結果にプロパティを設定するとですが、これらの結果は本質的には薄い空気に消えてしまいます。 foreachの後にのクエリの結果を列挙すると、クエリはに再実行され、が再実行され、結果が再現され、効果的に変更が元に戻されます。クエリは単なる結果ではなく、結果を生成するための仕様であることに注意してください。

簡単な修正はになります。最初にコレクションへのクエリ。

var result = myItems.GroupBy(x => new { Id = x.Id, Name = x.Name }) 
        .Select(x => new Report { Id = x.Key.Id, Name = x.Key.Name }) 
        .ToList(); 

あなたforeachはその後むしろ遅延クエリの結果より、メモリ内コレクションの要素を変異してしまうので、下流見えるであろう。

個人的に

しかし、クエリ自体にプロパティを設定することを検討:

var result = myItems.GroupBy(x => new { Id = x.Id, Name = x.Name }) 
        .Select(x => new Report 
           { 
            Id = x.Key.Id, 
            Name = x.Key.Name, 
            Sales = anotherCollection.First(a => a.Id == x.KeyId) 
                  .Sales 
            }); 
+0

私がmyItems.ToList()を先に実行してから、ToList()を使わずにGroupBy()を実行すると、それは動作しますか、それでも依然としてクエリが再実行されますか? – Thomas

+0

@Thomas:それは技術的にはうまくいくはずです。なぜなら、変更可能な 'Report'オブジェクトは既にその段階で作成され、実現されているからです。オブジェクトの作成ではなく、グループ分けだけが再実行されます。私はそれをしないことを強くお勧めします。 – Ani

+0

私はmyItems.ToList()を具体化する理由は、コレクションに複数のGroupBy(この質問には含まれていない)を行い、これらのコレクションを計算に使用したいからです。私の推論は、1つのデータベースクエリを実行してから、他のGroupByのインメモリコレクションを使用することです。なぜあなたはそれをすることをお勧めしないのですか? – Thomas

0

トーマス、

使用しているVaRの結果は、foreachループでは、あなたがそれを反復するとき、ちょうどクエリです新しいレポートオブジェクトを生成していますが、どこにも保存されていません。

は、問題を解決するために、クエリの最後にてToArray()またはToListメソッド()を追加します。

var result = myItems.GroupBy(x => new { Id = x.Id, Name = x.Name }).Select(x => new Report { Id = x.Key.Id, Name = x.Key.Name }).ToList(); 

アミール。

関連する問題