2014-01-17 3 views
7

私の信念は、いつも私ができる、Entity Frameworkはデータを取得する前または後にラムダ式を実行しますか?

SELECT * FROM big_data_set WHERE name = (someName)

ようしかし、それについて考えた後、​​がエンティティであり、あなたがvar someThing = Context.BigDataSet.Single(x => x.Name.Trim().ToUpper.Equals(someName.Trim().ToUpper()));を割り当てるならば、EFは、クエリにあなたのラムダ式を変換するために、いくつかの魔法を行いますことをされていますContext.BigDataSetの結果をメモリに保存して、、次にの検索を実行する以外は、動作する方法を確認してください。

EF DbSetラムダ式がSQLに変換されるのか、それとも後ですべて適用されるのですか?

編集:もしそれらがSQLに変換されたら、EFは名前をフェッチした後に起こることになるスタック全体を "どのように"見ることができますか?私がinstance.MethodA().MethodB()と呼ぶならば、それは通常、方法ABが逐次実行されるのではないのですか?

+0

似たような質問とそれに対する[良い答え](http://stackoverflow.com/a/4703001/1177964)がありました。 – Fedor

答えて

3

EF provider implementations. get lambdaではない式ツリーを取得します。 More about expressions in EF あなたの質問をもっと考えた後、私の推測ではあなたは使用された式について理解できませんでした。 Expression<Function<t,bool>> predicateとちょうどFunc<t,bool> predicateの違い。は重要。プロバイダはfuncを使用できません。それは表現木が必要です。

LINQのサブセットがあり、LINQのエンティティ標準に基づく式で使用できます。 supported queries

デバッガで試して、タイプExpression<Func<t,bool>>の変数の内容を見てください。 ラムダが式にどのように変換されたかをよく理解しており、DBプロバイダがSQLへの変換に使用するのはこの式です。

2

ストアドプロシージャ関数マッピングでラムダ操作を実行していない限り、それらはSQLに変換されます。 SQLプロファイラ(またはEFプロファイラ)を使用してこれを自分で確認し、クエリの実行時に生成されるSQLを調べることができます。

4

Entity Frameworkは、クエリを反復するまではデータベースにヒットしません。基本的にIQueryableの戻り値は、イテレートする時点でSQLクエリに変換されます。

var query = context.Employees; // Returns IQueryable<Employee> 

var employees = context.Employees.ToList(); // Returns List<Employee> (Hits the database) 

包括的な説明が必要な場合は、「Entity Framework Deferred Execution」を参照してください。

2

エンティティで直接呼び出されると、それらはSQLに変換されます。

結果をローカルにキャッシュして、エンティティのすべてのクエリでデータベースにヒットしないようにする場合は、即時実行を使用できます。 ToList()を経由して、これらのキャッシュされた値に対して複数のクエリを実行します。明らかに、これはすぐにデータベースにヒットしますが、一度だけです。

一般的にLINQクエリでは、結果のIEnumerableを反復処理するまで、作業は行われません(データベースにヒットしません)。

質問の2番目の部分は、クエリから生成されたSQLを表示すると分かります。試してみてください:

var query = Context.BigDataSet.Single(x => x.Name.Trim().ToUpper.Equals(someName.Trim().ToUpper())); 
var objectQuery=query as System.Data.Objects.ObjectQuery; 
Console.WriteLine(objectQuery.ToTraceString()); 
関連する問題