1

与えられた:

public EntityAddress ReadSingle(Func<EntityAddress, bool> predicate)
{
    //var result = Context.CV3Address.FirstOrDefault(a => a.GUID == 1100222);
    var result = Context.CV3Address.FirstOrDefault(predicate);
    return result;
}

FirstOrDefault(a => a.GUID == 1100222);すぐに結果を返します。

FirstOrDefault(predicate);タイムアウト例外が発生します。述語 = ラムダ式であることに注意してください

私の疑いでは、後者の方法は、これほど大きなテーブルでは起こらないすべてのレコードをプルダウンしようとすることです。

なぜこれが起こるのですか?

4

2 に答える 2

7

これは述語のタイプが原因で発生しますが、代わりに

Expression<Func<CV3Address, bool>>

述語が (上記のように) 式ツリーであり、Context.CV3Addressである場合IQueryable<CV3Address>、EF は式ツリーを SQL に変換し、データベースから直接結果を取得できます。

一方、述語がFunc<CV3Address, bool>(デリゲート; コンパイル済みコードへのポインター) である場合、これは SQL に変換できません。IEnumerable<CV3Address>したがって、LINQ には、メモリ内でフィルター処理できるシーケンスであるとしてリポジトリを処理する他のオプションはありません。これには、フィルター処理のためにデータベースからすべてのレコードをプルする必要があるという副作用があります。

述語をハードコードすると、コンパイラはそれを式ツリーまたはデリゲートのいずれかとして扱うことができ、その型によりContext.CV3Address式ツリーとして扱います。

于 2013-08-15T20:04:27.027 に答える
3

FirstOrDefault(a => a.GUID == 1100222)LINQ to Entities を使用して DB サーバーでクエリを実行する式ツリーを作成します。

FirstOrDefault(predicate)テーブル全体をダウンロードし、フィルターをローカルで実行します。

式ツリーを取得するには、メソッドを変更する必要があります。

Expression<Func<CV3Address, bool>>
于 2013-08-15T20:04:40.497 に答える