こんにちは、最近忙しい、和朗です。
今回は、現在利用しており今後も利用することになるであろう、EF6 と Linq について書いてみようと思います。
SQLのLog出力
これはなくてはならない機能! EFから発行されたSQLを簡単に見ることができます。SQL発行のタイミングもわかるので便利ですね。
[TestMethod] public void TestMethod1() { using (var db = new BlogContext()) { // 出力>デバッグにSQLを表示 db.Database.Log = x => System.Diagnostics.Debug.WriteLine(x); System.Diagnostics.Debug.WriteLine("Blogs:{0}件", db.Blogs.Count()); } }
ログ出力
Opened connection at 2015/08/31 18:21:50 +09:00 SELECT `GroupBy1`.`A1` AS `C1` FROM (SELECT COUNT(1) AS `A1` FROM `Blogs` AS `Extent1`) AS `GroupBy1` -- Executing at 2015/08/31 18:21:50 +09:00 -- Completed in 4 ms with result: EFMySqlDataReader Closed connection at 2015/08/31 18:21:50 +09:00 Blogs:495件
.AsNoTracking()
SQLにwith(nolock)をつけているイメージ。更新の必要の無いデータにアクセスする場合はAsNotrackingを利用したほうがパフォーマンスがアップするようです。
[TestMethod] public void TestMethod2() { using (var db = new BlogContext()) { var data = db.Blogs.AsNoTracking().Where(b => b.name = "1"); foreach (var item in data) { System.Diagnostics.Debug.WriteLine("{0}:{1}", item.name, item.context); } } }
Entity Framework and AsNoTracking←パフォーマンスについては、2-3割ぐらい早くなるようですね。
遅延評価を利用しない
ToArray()を利用することでSQLを発行し、結果を確定させる。
ToArrayした後のオブジェクトにアクセスしても、SQLが発行されることはない。
実際は遅延評価を利用しない訳ではなく、任意のタイミングで評価させる。
IEnumerable
[TestMethod] public void TestMethod3() { using (var db = new BlogContext()) { var data = db.Blogs.ToList(); var dataArray = data.ToArray(); var dataA = data.Select(~~); var dataB = dataArray.Select(~~); } }
.Skip() と .Take()
一覧表示を行う際に必要となってくるページング処理で利用します。 Whereでデータを絞ったあとに、.OrderBy()を行い、必要なデータを取得します。
[TestMethod] public void TestMethod4() { var pageSize = 20; var pageIndex = 3; using (var db = new BlogContext()) { var data = db.Blogs.Where(~~~); var target = data.OrderBy(x => x.id) .Skip(pageSize * (pageIndex)).Take(pageSize); } }
大文字小文字の区別
SQLSERVERの照合順序はデフォルト大文字小文字を区別しないため、注意が必要。 私は以前、パフォーマンスアップのためにSQLからLinqにリファクタを行ったはずが結果セットが一致せず、悩みました。もちろんLinqは大文字小文字を区別します。
[TestMethod] public void TestMethod5() { using (var db = new BlogContext()) { var data = db.Blogs.Where(b => b.name.Lower().Contains("a")); } }
まとめ
EF6になって全体的なパフォーマンスはアップしたと聞きますが、 SQLを書くときと同様にパフォーマンスを意識したコードが必要だと感じます。 ちょっとした実装方法の違いで劇的にパフォーマンスが悪くなったりするので、Logを見ながら改善が必要ですね!