8

サイトを持つ単純な DB があり、各サイトには多数の投稿があります。

特定のサイトのすべての「公開」投稿を取得しようとしています (すでに EF によってもたらされたインスタンスである site という変数があります)

最初の明らかなことは次のとおりです。

  var posts = from post in site.Posts
              where post.Public == true
              orderby post.PublicationTime descending
              select post;

これは私が望むものをもたらしますが、SQL Server Profiler を見ると、WHERE のみがサイトではなく Public フィールドをフィルタリングしています。実際、Profiler がキャプチャしたクエリを SQL Server で実行すると、実際にすべてのサイトからすべての投稿が返されます (これは後で ASP.Net 側で明らかにフィルタリングされます)。

それから私は試しました:

  var posts = from post in db.Posts
              where post.Site == site && post.Public == true
              orderby post.PublicationTime descending
              select post;

同じ結果です。

私はここで根本的に愚かなことをしていますか?
Entity Framework は常にクライアント側でフィルターをかけますか?

ありがとう!
ダニエル

4

2 に答える 2

10

LINQtoEntitiesとLINQtoObjectsの違いを理解する必要があります。Entity Frameworkを使用する場合は、これを追跡することが非常に重要です。

ObjectContextに対してクエリを発行すると、LINQtoEntitiesで作業します。これにより、IQueryableが返されます。IQueryable型の変数を使用している限り、LINQ APIを使用してクエリをさらに作成でき、最終的に結果を列挙すると、SQLに変換されます。

しかし、あなたは言います:

(私はすでにEFによってもたらされたインスタンスであるsiteと呼ばれる変数を持っています)

ここでは、オブジェクトのプロパティをクエリしているため、LINQ to Entitiesではなく、LINQtoObjectsで作業しています。これは、クエリに別のプロバイダーがあり、SQLに変換されないことを意味します。

2番目のクエリについて:

var posts = from post in db.Posts
            where post.Site == site && post.Public == true
            orderby post.PublicationTime descending
            select post;

EFでは、L2EのインスタンスでID比較を行うことはできません。代わりにキーを比較する必要があります。試す:

var posts = from post in db.Posts
            where post.Site.Id == site.Id && post.Public
            orderby post.PublicationTime descending
            select post;

ところで、私はに変更post.Public == trueしましたpost.Public。きれいだと思います。

于 2010-02-11T14:00:00.957 に答える
6

メソッド構文を使用してこれに問題がある場合:

Func<TEntity,Boolean>メソッドに aを渡すと.Where、クエリがデータベースから返された後にフィルター関数が適用されます。これは、.Whereメソッドの戻り値が IEnumerable を返すためです。一方、メソッドに を渡すExpression<Func<TEntity,Boolean>.Where、フィルター関数はデータベースに送信される where 句を生成します。これは、.Whereが IQueryable を返すためです。IQueryables に固執する限り、データベースに送信するクエリを作成しています。IEnumerable を返すと、メソッドの前のすべてがクエリの作成に使用され、IEnumerable の後のすべてが返されたものに適用されます。これは、ラムダ関数を変数に格納する場合にのみ重要です。ラムダを直接渡した場合.Where通常、問題はありません。お役に立てれば!!

IEnumerable どこで: https://msdn.microsoft.com/en-us/library/bb549418(v=vs.110).aspx

IQueryable 場所: https://msdn.microsoft.com/en-us/library/bb535040(v=vs.110).aspx

于 2017-01-31T16:21:24.537 に答える