2012-05-07 29 views
1

私のリポジトリから、ToList()メソッドを使用して別のListを返します。ToList()メソッド呼び出し時にデータベースを呼び出す

問題は、この返された結果(つまりList型)でさらにLINQを実行すると、これもデータベース呼び出しを生成することです。明らかに、この2番目のlinq calllは純粋なLINQ to Entityであり、データベースは呼び出されません。私がしていることを以下に見てください。

List<User> us = userRepository.GetMany(u => filterStatusIds.Contains(u.UserStatus.Id)); 
if (!string.IsNullOrEmpty(name)) 
us = (from u in us 
     where u.DisplayName.Contains(name) 
     select u).ToList(); // this ToList should not call database 

この追加のデータベースコールを停止するための助けやアイデアはありますか?

+1

なぜデータベースクエリーを再度実行すると思いますか?また、なぜデータベースの代わりにアプリケーションでフィルタを実行するのですか? –

+0

@abatishchev: 'ToList'への最初の呼び出しは、linq-to-objectsに切り替わり、結果が実体化され、式ツリーがなくなるため、戻ってくることはありません。 –

+0

@ラディスラフ:確かに、そうです、最初のコメントを誤解しました。 – abatishchev

答えて

1

IEnumerable<User>またはIQueryable<T>をリポジトリから返すと、データベースにクエリが実行されません。

ToList()の後に2番目の呼び出しでのみこれが実行されます。

+0

興味深い - 最初のクエリで 'List 'の戻り値型が結果の列挙を強制するのでしょうか?私。 'IEnumerable'と' List'の間にある種のキャストだけではありませんが、結果のマテリアライゼーション( 'ToList()'は暗黙的です)を含んでいますか?それはおそらく私には明らかですが、あなたが確認できれば幸いです。 –

+0

私はフィルターをかけたList の簡単な例を試しました。コンパイラーは 'ToList'を呼び出さずに、IEnumerableを暗黙的にリストに変換できないと私に言っただけです。この例では違いますか?この例の最初の行ではどのように動作しますか? –

+0

@ Joanna:はい、ToArray()/ ToList()を呼び出すとマテリアライゼーションが発生します。メソッドが単にIEnumerable /IQueryable を "そのまま"返した場合、マテリアライゼーションは発生しません。最初のm-zの後、LINQからEntities、LINQ to Objectsに切り替えます。つまり、最初のフィルタリング結果をサーバーメモリにロードし、次のすべてのフィルタでメモリに列挙します。 – abatishchev

関連する問題