ASP.NET Core(EF Core)でMySQLを使う 2016年11月編


ASP.NET Core 1.0がリリースされて久しいですが、いっこうにMySQLでの利用サンプル（特にモデルファースト）が無いので調べてみた結果をとりあえずメモ。

この記事は古いので、[2017年5月編](http://qiita.com/zaburo/items/cd6882305110857c8a50)をご覧くさい。

##環境

* OS:El Capitan(Sierraでも問題なし）
* MySQL 5.5(MAMP付属のもの）
* .NET Coreは1.0（[ここからダウンロードしてインストール](https://www.microsoft.com/net/core#macos)）
* yo（テンプレート生成）

環境構築については私の記事もありますが、少々古いので[ここ](http://gooner.hateblo.jp/entry/2016/10/11/044948)が参考になるかと。

##どのプロバイダを使うか？

[マイクロソフト](https://docs.microsoft.com/en-us/ef/core/providers/)のサンプルページでは下記の3種類紹介されています。

###Official

MySQLのオフィシャルらしい。が、更新が夏頃からされておらずやる気が感じられない。
[このページ](http://insidemysql.com/howto-starting-with-mysql-ef-core-provider-and-connectornet-7-0-4/)などが参考になる。

###Pomelo

雰囲気良さそう。[GitHubの情報](https://github.com/PomeloFoundation/Pomelo.EntityFrameworkCore.MySql)で何とかなりそう。

###Sapient Guardian

Pomeloに比べると[GitHub上の活性](https://github.com/SapientGuardian/SapientGuardian.EntityFrameworkCore.MySql)は低いかな。。。

というわけでとりあえずPomeloとやらを利用してみることにします。

##MySQLからデータを取得してみる

とりあずSELECTしてみる。タイトルはASP.NETとしたが、コードが複雑になるのでConsoleアプリとして実装してみます。

###MySQLにテーブルを作成する

今回はサンプルなので簡単なテーブルにします。なお、Entity Frameworkを利用するにはテーブルに主キーが必要なので定義しておきましょう。

membersというテーブルを作り、idとnameとemailのカラムを作ります。
サンプルデータもインサートしておきます。

```sql
#CREATE TABLE
create table members(
	id int primary key auto_increment,
	name varchar(32),
	email varchar(64)
);

#SAMPLE INSERT
insert into members(name,email) values('hoge','hoge@hoge.com');
insert into members(name,email) values('foo','foo@foo.com');
```

###yoでConsole Applicationテンプレートを生成

yo -> ASP.NET -> Console Applicationと選択し、テンプレートを生成します。
初期状態で下記３つのファイルが出来ているはずです。

* .gitignore
* Program.cs
* project.json

必要なのは下記２つだけ。

###project.jsonの編集

project.jsonのdependenciesにPomeloを追加し、restoreします。
>以下、dependenciesだけ抜粋。

```diff
  "dependencies": {
    "Microsoft.NETCore.App": {
      "type": "platform",
      "version": "1.0.1"
    },
+    "Pomelo.EntityFrameworkCore.MySql": "1.1.0-*",
+    "Microsoft.EntityFrameworkCore.Tools": "1.1.0-preview4-final"
  },
```
package.jsonを編集したら忘れずにrestoreし、必要なファイルを取得します。

```bash
dotnet restore
```

###Program.csを編集

本当はModelを別クラスにした方が分かりやすいですが、面倒なのでProgram.csに全て書きます。
Entity Frameworkを経由してデータベースを利用するためには、

* テーブルに相当するModelクラス
* テーブル（データベース）とモデルクラスをマップするContextクラス

の2つを最低限定義する必要があります。以下の通り定義します。

```csharp
using System;
using System.Linq;
using Microsoft.EntityFrameworkCore;

namespace myapp1
{
    public class Program
    {

        //Model
        public class Member
        {
            public int id {get; set;}
            public string name {get; set;}
            public string email {get; set;}
        }

        //Context
        public class MyContext : DbContext
        {
            public DbSet<Member> Members {get; set;}
            protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
                => optionsBuilder.UseMySql(@"server=localhost;database=testdb;uid=root;pwd=root;");
        }


        //Main
        public static void Main(string[] args)
        {
            using(var context = new MyContext())
            {
                var ret = context.Members
                    .ToList();

                foreach(var x in ret)
                {
                    Console.WriteLine($"{x.name} {x.email}");
                }
            }
        }
    }
}

```

###実行する

コーディングが完了したら実行します。

```bash
dotnet run

hoge hoge@hoge.com
foo foo@foo.com
```

うまくいったようです。

###その他

いちおう挿入・更新・削除なども。usingステートメントの中に書きましょう。
Linq使うとか、LIKEはどうすんだ？とかいろいろありますが、それはEntity Frameworkの使い方調べましょう。

```csharp
//insert
var member = new Member();
member.name = "tanaka";
member.email = "tanaka@test.com";

context.Add(member);
context.SaveChanges();

//update
var member = context.Members.Single(x=> x.name == "tanaka");
member.name = "suzuki";
context.SaveChanges();


//delete
var member = context.Members.Single(x=> x.name == "suzuki");
context.Members.Remove(member);
context.SaveChanges();
```