6

作業を開始するのに時間がかかったデータ アクセス クラスがあります。私のアプリでは、WHERE 句が列名だけが異なるさまざまな種類の SQL Server テーブルを取得する必要があります。いくつかの列は read_time で、他は ReadTime で、他は LastModifiedTime です。そこで、50 の異なるテーブルに対して新しいメソッドを作成する必要がないように、WHERE 句を渡すことにしました。シンプルに見えて動作しますが、何かわかりません。

パラメータとして Expression<> を使用したこのメソッドは機能します。

internal List<T> GetObjectsGreaterThanReadTime<T>(Expression<Func<T, bool>> whereClause) where T : class
{
    Table<T> table = this.Database.GetTable<T>();
    IEnumerable<T> objects = table.Where(whereClause);

    return objects.ToList();
}

今、私はしばらくの間、この方法 (以下) を試していましたが、最後の行 (ToList()) でハングするだけでした。まず、なぜこれがコンパイルされるのでしょうか? つまり、なぜ Expression と Func をパラメーターとして同じ意味で使用できるのでしょうか? では、なぜ Expression は機能するのに、Func バージョンはハングアップするのでしょうか?

注: 上記のメソッドとこのメソッドの唯一の違いは、メソッドのパラメーター (Expression と Func) です。

internal List<T> GetObjectsGreaterThanReadTime<T>(Func<T, bool> whereClause) where T : class
{
    Table<T> table = this.Database.GetTable<T>();
    IEnumerable<T> objects = table.Where(whereClause);

    return objects.ToList();
}
4

1 に答える 1

12

Queryable.Where式ツリーを生成するExpression バージョンの呼び出しは、( によって列挙されるToListと) sql に変換され、データベース サーバー上で実行されます。おそらく、データベース サーバーはフィルター条件に基づいてインデックスを利用し、テーブル全体を読み取らないようにします。

Func バージョンはEnumerable.Where、(によって列挙された場合ToList)テーブル全体をロードし(ハングとして認識されるもの)、メモリ内オブジェクトに対してフィルター条件を実行する呼び出しを行います。

于 2012-04-04T18:06:17.780 に答える