井上です。
SQL Server同様、MySQLでもEntity FrameworkとLINQを用いて当然やりたいですよね。
環境
.NET Framework 4.5.1
MySQL Entity Framework 6
MySQL 5.6
C#
Entity Framework・LINQを用いるメリット
何故Entity Frameworkを使いたいかとなると、以下の様なメリットがあるからです。
データベースの定義変更に強い
DBの定義更新があった場合、モデル(edmxファイル)を更新することでプログラムに即反映できます。
DataSet等だとこれは出来ないので大きなメリットだと思います。
とにかく開発効率が良い
実際書いてみるとわかりますが1行でSELECTでき、且つ取得結果を好きな形で返せるというのは大きいです。 DBという意識無く書けるのはすごいですよね。
Entity Framework・LINQを用いたことによるデメリット
想定と異なるSQLが生成される
MySQLだからというよりEntity Frameworkによるところも多いかと思いますが、メソッドチェーンでJoin/GroupJoinを複数行うような場合、パフォーマンスが出ず致命的になる場合もあります。
遅延実行に注意しないといけない
実際にSQLが実行されるタイミングは結果が必要になるとき(Count(),ToList(), ToArray()等)なので、そのタイミングを考えてコードを書く必要があります。
LINQで日付条件比較が一致しない
MySQLのdate型はC#のDateTime型にマッピングされています。
DateTime target= new DateTime(2015, 12, 01); var result = db.TableA.Where(x => x.date_column == target).ToList();
当然こんな風に書きたいところですが、残念ながらdate_columnカラム値が2015-12-01
の値となっているレコードは取得されません。
1ミリ秒ずらすという苦肉の策で期待通りの結果は得られるようになりました。
DateTime from= new DateTime(2015, 12, 01); DateTime to = searchDate.AddMilliseconds(-1); var result = db.TableA.Where(x => x.date_column >= from && x.date_column <= to).ToList();
尚、SqlQueryで直接SQLParameter指定した場合は普通に期待通りの結果がかえってきます。
using (var db = new hogehogeEntities()) { string sql = "SELECT hogehoge FROM TableA WHERE date_column = @targetdate"; List<MySql.Data.MySqlClient.MySqlParameter> parameters = new List<MySql.Data.MySqlClient.MySqlParameter>(); parameters.Add(new MySql.Data.MySqlClient.MySqlParameter("@targetdate", MySql.Data.MySqlClient.MySqlDbType.Date)); parameters[0].Value = targetdate; var result = db.Database.SqlQuery<クラス>(sql, parameters.ToArray()).ToList(); }
そもそものMySQLとC#間の問題
Entity FrameworkおよびLINQとは関係ありませんが。
日付の初期値
MySQLのDateTimeの最小値は[0000-00-00 00:00:00]ですが、C#のDateTime型は最小値が[0001-01-01 00:00:00]です。
このためそのままMySQLの値を代入すると例外が発生します。
DB接続文字列にConvert Zero Datetime=true
を追加することで代入不可な日付値をMinValueに自動的に変換してくれます。
BLOB型を追加・更新できない
こちらに記載しています。
C#EF6からMySQL-BLOBにデータを登録 - Sanwa Systems Tech Blog
まとめ
個人的にはラップすると内部で何やってるのか見えなくなってしまうので、SQLは直に書きたいところですが、LINQは時と場合で非常に強力なのは事実・・・。
多くのJOINを重ねたりするととってもボリューミーなSQLが自動生成されてしまったりするのでどこまでLINQでやるべきなのか等チーム内で決めるのが大事かと思います。
複雑なSQL書くなよって話もあるかと思いますが、回避できないときも多々あるかと思いますので。
以下ブログも参考いただければ幸いです。
Entity Framework と Linq を使いこなしたい! - Sanwa Systems Tech Blog LINQ(メソッド構文)を用いた複雑めなSQL発行時のメモ - Sanwa Systems Tech Blog