3

私のEntityFrameworkCode Firstプロジェクトには、ルートを含むリポジトリオブジェクトがあります

public class EFRepository
{
    ...
    public IQueryable<Route> Routes
    {
        get { return context.Routes; }
    }
   ...
}

私が走ったら

var routes = this.repository.Routes
                  .Where(r => r.DeployedService.IsActive.HasValue 
                   && r.DeployedService.IsActive.Value);

ルートオブジェクトのタイプはIQueryable<Route>です。

しかし、私が実行した場合

Func<Route, bool> routeIsActive = r => r.DeployedService.IsActive.HasValue 
                                      && r.DeployedService.IsActive.Value;
var routes = this.repository.Routes.Where(routeIsActive);

この場合のroutesオブジェクトのタイプはIEnumerable<Route>です。

私は彼らが同じように評価されるだろうと思っていたでしょうが、明らかに私は間違っています。2つのステートメントの違いは何ですか?また、なぜそれらは異なるタイプを返すのですか?

4

3 に答える 3

5

メソッド.Where(Expression<Func<Route,bool>>)はによって定義されIQueryable<Route>ます。一方、メソッド.Where(Func<Route,bool>)はによって定義され、によって定義されIEnumerable<Route>ませんIQueryable<Route>。したがって、それぞれが流暢なLINQメソッドチェーンに対して独自のタイプを返します。

によって定義された追加のメソッドをIQueryable使用すると、式ツリーをLINQプロバイダー(例:LINQ-to-entities)にプッシュダウンして、可能な場合はプロバイダーレベルでの遅延評価を行うことができます。

于 2012-07-18T10:13:55.090 に答える
4

渡すFunc<Route,bool>と、Linq-to-objects(Func.NETコードで実行される.NETデリゲート)になるためです。それはEFに伝えます:すべてのルートをロードし、.NETコードでフィルタリングを行います。

Expression<Func<Route,bool>>Linq-to-entitiesを操作するには、SQLに内部的に変換される式()を渡す必要があります。これはEFに通知します。これがSQLに変換してデータベースサーバーで実行するフィルターであり、フィルター処理された結果セットのみを受け取りたいと考えています。

于 2012-07-18T10:11:17.920 に答える
2

IQuerable<T>から継承しIEnumerable<T>ます。これは、それWhereが過負荷であることを意味します。

1つのオーバーロードは式を受け取り、を返しますIQuerable<T>

public static IQueryable<TSource> Where<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, bool>> predicate)

もう1つのオーバーロードは関数を受け取り、を返しますIEnumerable<T>

public static IQueryable<TSource> Where<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)

ラムダを渡すと、両方のオーバーロードが適用可能になり、オーバーロード解決では最初のオーバーロードが優先されます。を渡すとFunc<T,bool>、2番目のオーバーロードのみが適用されます。

変数のタイプをに変更するとExpression<Func<Route, bool>>IQueryable<Route>元に戻ります。

于 2012-07-18T10:14:31.733 に答える