2012-04-04 41 views
6

私はデータアクセスクラスを持っています。私のアプリケーションでは、WHERE句は列名によって異なるSQL Serverテーブルの異なるタイプを取得する必要があります。いくつかの列はread_time、その他はReadTime、その他はLastModifiedTimeです。だから私はWHERE句を渡すと思ったので、50種類のテーブルに対して新しいメソッドを作成する必要はありませんでした。それはシンプルに見え、うまくいくが、私は何かを理解していない。パラメータとして表現<となぜFunc <>と式<Func<>>は互換性がありますか?なぜ私の場合は1つ働くのですか?

この方法で、>、作品:

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 vs. 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(); 
} 
+3

これは、回答と併せて、それ自体、「表現木のポイントは何ですか?」のいくつかに対する非常に良い応答です。スタイルの質問。 +1 Q&A –

答えて

12

発現バージョンでは、SQLに変換し、データベース・サーバ上で実行される(ToListによって列挙とき)式ツリーを生成Queryable.Whereを呼び出します。おそらく、データベース・サーバーは、フィルターの基準に基づいて索引を使用して、表全体を読み取らないようにします。

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

+0

Ahhhhhhhhhhhh ...いいです。完全に意味をなさないありがとうございました! –

関連する問題