2015年09月17日

EntityFramework(4):遅延実行と即時実行

   このエントリーをはてなブックマークに追加 Clip to Evernote
▪️遅延実行

LINQを使ったクエリ操作は、次の3つの手順を取ります。

 1.データ ソースを取得します。 
 2.クエリを作成します。 
 3.クエリを実行します。

以前にもお見せした以下のコード(今回はメソッド形式にしています)と 照らし合わせてみましょう。

 using (var db = new NorthwindContext()) {
     var query = db.Products
                   .Where(x => x.UnitPrice < 10);
     foreach (var p in query)
         Console.WriteLine("{0} | {1} | {2} | {3}",
             p.ProductID, p.ProductName, p.CategoryID, p.UnitPrice);
 }

NorthwindContext() をnewしている箇所が、「データソースを取得」してい るところです。 EntityFrameworkでは、必ず、DbContextを生成するところから操作が始まります。
次にクエリを作成し変数queryに代入しています。重要なのは、ここではまだクエリは発行されていないということです。 単に「クエリ式」がquery変数に代入されているだけです。
実際のクエリは、foreachステートメントでクエリ変数が反復処理されるまで延期されます。これを「遅延実行」と言います。LINQ to Objectと同じですね。

この性質を利用すれば、最新のデータを取得するクエリを一つ用意し、それを、何回も使うということが出来ます。この場合、(その間でデータが更新されていれば)毎回異なった結果を得ることになります。

さらに遅延実行の性質から、以下のようにクエリ式をつなげることができます。

 using (var db = new NorthwindContext()) {
     var query = from product in db.Products
                 where product.UnitPrice < 10
                 select product;
     var query2 = from product in query  // queryを入力にしている
                  where product.ProductName.StartsWith("T")
                  select product;
     foreach (var p in query2)
         Console.WriteLine("{0} | {1} | {2} | {3}",
             p.ProductID, p.ProductName, p.CategoryID, p.UnitPrice);
 }

これは、遅延実行の利点の 1 つと捕らえることができます。
単純なクエリ式の組み合わせで、複雑なクエリを作り出すことが出来るのです。
もちろん、実施のSQLが発行されるときには、一つのSQL文として発行されます。

※ここで示したサンプルは、あくまでも、機能を示すためのものです。 この程度ならば、わざわざ2つに分割する必要はありませんね。


▪️即時実行

一方、Count,Max, First, Sum などSQLの集計関数を実行するクエリでは 遅延実行はされません。
例えば、

 var count = db.Products
               .Where(x => x.UnitPrice < 10)
               .Count();

というステートメントでは、即SQL文が発行され、count変数にその結果が格納され ます。
遅延実行されるクエリについて、即時実行を強制し、その結果をキャッシュした い場合には、ToList()、ToArray()を呼び出します。

  var list = db.Products
               .Where(x => x.UnitPrice < 10)
               .ToList();

とすれば、ToList()メソッドを呼び出した時点で、SQLが発行され、その結果が、 Listに変換されます。
これ以降 list変数へのアクセスでは、SQL文が発行されることはありません。
 


 

この記事へのトラックバックURL

http://trackback.blogsys.jp/livedoor/gushwell/52435922