読者です 読者をやめる 読者になる 読者になる

C#でEF+LINQを用いてMySQLを使用するメリット・デメリット

C#

井上です。
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();
}

そもそものMySQLC#間の問題

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