Tech・days 2010 デモのフォローアップ 3 遅延ロードとNative SQL 編【T2-305 ADO.NET Entity Framework】
一先ずセミナーや執筆など諸々終わったので一安心・・・・と思ったのもつかの間、残していた事務作業がテンコ盛りの今日この頃です。まぁ、見ないことにして Blog を Update したいと思います。
今日は遅延ロードと Native SQL を扱います。次回は POCO と Self-Tracking Entities を予定しています。
遅延ロード(レイジーロード)
必要になったタイミングで暗黙的にデータを取得する機能ですね。
下記のコード例では6行目の CourseGrades を取得するタイミングで毎回、クエリが発行されます。
(尚、デフォルトで遅延ロードは true になっています。要するに ON 。)
このコードでは People の件数と同じだけ CourseGrades を取得するためのクエリが発行されます。
6名のデータが存在すれば、CourseGrades を取得するために 6 回クエリが発行されることになります。
よって、開発者は CourseGrade データのロードを意識しないでよいため楽ちんですが、ラウンドトリップ回数はパフォーマンスに悪影響を与える可能性があるため意識する必要があります。
// デフォルトは true です。 db.ContextOptions.LazyLoadingEnabled = true; var people = db.People; foreach (var p in people) { Console.WriteLine(p.Name); foreach (var cg in p.CourseGrades) { Console.WriteLine(" " + cg.CourseName + " : " + cg.Grade); } } |
次のように修正してやると一発でデータを取得できます。
var people = db.People.Include("CourseGrades"); |
もともと遅延ロードについては こちらの記事 にもある通り、次の理由により敢えて実装されていなかったという背景があります。
・隠されたネットワーク ラウンドトリップは排除すべき
・ロードされるタイミングが異なるためデータ一貫性に問題が発生する可能性がある
とはいえ、次のようなメリットがあり「遅延ロードが欲しい!!」というフィードバックが多数寄せられ、EF 4 では実装されることになりました。
・明示的にロードを意識しなくてよいので楽ちん
・コードが冗長にならない
無闇矢鱈に利用するのでなく、このあたりのメリット、デメリットを理解した上で是非利用してみてください。
以前の記事 もご参考まで。
Native SQL
こちらはシンプルにNativeのSQL文が実行できるようになったという機能です。
今のところ、この機能が一番評判がいいような気がするので若干微妙ですが・・・・・・
本セッションでは対象にしませんでしたが、EF 4 では生成されるクエリの大幅なパフォーマンスチューングが施されており、V1 と比較すると速度の向上が見込めると思います。
しかしながら、システムのある個所だけどうしてもパフォーマンスがでないケース、どうしてもデータベース固有のコマンドが利用したいケース等々あると思います。そのような時に威力を発揮するのがこの Native SQL の機能です。
構文とサンプルソースを以下に示します。
構文(C#)
public ObjectResult<TElement> ExecuteStoreQuery<TElement>( string commandText, params Object[] parameters ) |
public int ExecuteStoreCommand( string commandText, params Object[] parameters ) |
サンプル(C#)
using (schooldbEntities db = new schooldbEntities()) { string name = "井上 大輔"; IEnumerable<Person> schools = db.ExecuteStoreQuery<Person>("SELECT * FROM People where name = {0}", name); foreach (var s in schools) { Console.WriteLine(s.Name); } } |
string name = "井上 章"; int pid = 3; int count = db.ExecuteStoreCommand("Update People set name = {0} Where PersonId = {1}", name, pid); |
以前の記事 もご参考まで。