概要
ASP.NET Core MVCテンプレートとMySQLの組み合わせで操作を実行すると何かしらDBに操作(CRUD)を加えた段階で
No coercion operator is defined between types 'System.Int16' and 'System.Boolean'
と言うエラーが発生しました。
その回避策のメモです。
当初、MySQLへの接続プロバイダ(コネクタ?)はOracle公式のMySql.Data.EntityFrameworkCore
を使っていましたが
エラー回避のためにOSSのPomelo.EntityFrameworkCore.MySql
へ変更しました。
目次
環境
- MacOS Mojave Version 10.14.3
- .Net Core SDK Version 2.2.104
- Docker Version 18.09.2
- Docker image : MySQL 5.7(公式)
参考サイト
- https://github.com/aspnet/EntityFrameworkCore/issues/14051 🔗
- https://dev.mysql.com/doc/connector-net/en/ 🔗
- https://github.com/PomeloFoundation 🔗
- https://docs.microsoft.com/ja-jp/ef/core/providers/ 🔗
使用したプロジェクト
https://github.com/Lycheejam/blog-sample/tree/master/using-mysql-package 🔗
前提
プロジェクトについては新規作成の上、Oracle公式のMySQL接続プロバイダーを追加しています。
接続設定情報については前回記事のDBを使いまわしているため同様です。
テンプレートからの変更箇所はGitのコミットログで確認できます。
※中括弧の修正も巻き込まれてて余計な部分も修正されたように見えてます…
https://github.com/Lycheejam/blog-sample/commit/42cc530deeefda0dc74c690c599e64d710f62ee8 🔗
プロジェクト作成
$ dotnet new mvc -n using-mysql-package -au Individual
$ cd using-mysql-package/
$ dotnet add package MySql.Data.EntityFrameworkCore
MySQL
Docker上で稼働させたMySQLを使用しています。
前回の記事のものをそのまま使用しています。
事象
ASP.NET Core MVCの個人認証付きテンプレートを使用してMySQLへ操作を行った。
ここでの操作とはユーザ登録操作である。
その際に下記のエラーが発生しユーザ登録を完了することができなかった。
An unhandled exception occurred while processing the request.
InvalidOperationException: No coercion operator is defined between types 'System.Int16' and 'System.Boolean'.
System.Linq.Expressions.Expression.GetUserDefinedCoercionOrThrow(ExpressionType coercionType, Expression expression, Type convertToType)
原因
不明。
私の技術知識では原因まで追うことができなかった。
本件に言及されているissue
https://github.com/aspnet/EntityFrameworkCore/issues/14051 🔗
ISSUEにはOracle公式のMySQL接続プロバイダー側に何かしらの不備があるんでない?と言う風に書かれていた。
MySQL公式の.NET(Core)向けドキュメントによれば.NET Core 2.2はサポート範囲外の様なのでエラーとなっても文句は言えないなと言う感じである。
サポート情報
https://dev.mysql.com/doc/connector-net/en/connector-net-entityframework-core.html 🔗
回避策
Oracleの公式接続プロバイダー(MySql.Data.EntityFrameworkCore
)ではなく
Pomeloと言うOSSの接続プロバイダーを使用するように変更します。
https://github.com/PomeloFoundation/Pomelo.EntityFrameworkCore.MySql 🔗
プロジェクトにPomeloを追加します。
//プロジェクトディレクトリにて ※適宜Oracleの接続コネクターを削除してください。
$ dotnet add package Pomelo.EntityFrameworkCore.MySql
Startup.cs
で定義しているDBへの接続設定をOracle公式のものからPomeloに変更します。
両者の表記上の違いはUseMySQL
かUseMySql
かの大文字小文字の違いになります。
ですので不要となったOracleのパッケージは削除したほうが無難かなと思います。
インテリセンスで紛らわしいので。
Startup.cs
public void ConfigureServices(IServiceCollection services) {
//省略
services.AddDbContext<ApplicationDbContext>(options =>
//MySql.Data.EntityFrameworkCoreのUseMySQL
//options.UseMySQL(Configuration.GetConnectionString("MySQLConnection")));
//Pomelo.EntityFrameworkCore.MySqlのUseMySql
options.UseMySql(Configuration.GetConnectionString("MySQLConnection")));
//省略
}
上記設定完了後、動作確認を行いエラーが発生しないことをご確認ください。
雑感
PomeloとOracle公式とで何が違うのかを言及できればよかったんですが
英語での解説ばかりで全然理解が進みませんでした。
とりあえず動けばいいやでPomelo使ってます。
Microsoft公式のドキュメントにも記載があるので非公式のコミュニティーOSSというわけでもなさそう。