6

私はそのようなインターフェースを持っています...

public interface IAccountRepository : IDisposable {
    IQueryable<Account> FindByUserId(int userId); //here, Resharper says "Return type can be IEnumerable<Account>"
}

しかし、Resharper は、IEnumerable<Account> FindByUserId(int userId)代わりに変更することを提案しています。

どうしてこんなことに?オブジェクト全体を強制的にメモリにロードすることはありませんか? オブジェクトが本当に必要になるまで実行を延期したほうがよいと思いましたか?

4

3 に答える 3

6

答えは「いいえ、しかしです。

IEnumerable にキャストしても実行は強制されません。IEnumerable 空間内の演算子 ("Where" メソッドなど) は引き続き遅延評価できます。

しかし、ここで注意点があります。このメソッド内で LINQ 演算子の使用を開始すると、LINQ はGroupBy (IQueryable)などのクエリ可能な演算子ではなく、GroupBy (IEnumerable)などの列挙可能な LINQ 演算子を選択します。パラメータ リストが異なることに注意してください。

これにより、渡された Lambda 式が Expression> ではなく Func に変換されます (2 つのそれぞれのメソッドのパラメーター リストの違いに注意してください)。したがって、ラムダは式ツリーではありません。これは、クエリをサーバー経由で渡してサーバー側で実行できるように、クエリ可能なソースが SQL (または同様のもの) に変換するために必要なものです。

したがって、クエリは遅くなります。キャストすると実行されるからではなく、データソースからアイテムを取得しようとすると、データソース全体がクライアントにプルされるためです。

もちろん、これは、このメソッド内で LINQ の使用を開始する (「Where」句などを追加する) 場合のみです。そうでない場合は、大丈夫です。

于 2013-07-28T05:29:03.463 に答える
1

IQueryableIEnumerableは既に( MSDN )から継承しているため、必要な異論IEnumerableはまだあります。ReSharper はIEnumerable、すべての実装が返された場合でもメソッドが返されるように定義されている可能性があることを示していますIQueryable(呼び出しが必要な場合は、IQueryable代わりにMSDNIEnumerableを呼び出すことができAsQueryableます) 。

また、 のメンバーは、IEnumerable列挙されたときにのみ取得されます。つまり、たとえば、各メンバーが個別の Web サービス呼び出しによって取得された場合でも、それらの呼び出しは、特定のメンバーが要求されたときにのみ行われます。

于 2013-07-27T23:25:24.040 に答える