Entity Framework Coreを使用してデータベースのマイグレーションを行う

## Entity Framework Coreとは

.Net coreのデータベース関連を担うパッケージです。
公式には、

* .NET 開発者が .NET オブジェクトを使用してデータベースを操作できるようにする。
* 通常記述しなければならないデータアクセス コードの多くを不要にする。

などとあり、データベースの操作を簡単にするパッケージです。

基本的に、このEF Coreを使用すればSQL文を記述せずにデータベースのマイグレーション、データベースへのデータ挿入、取得をコードベース(c#)で行うことができます。

## SQL文ベースで使いたいあなたへ
個人的にまだ、SQL文の記述に慣れていないため。できればSQL文を記述し、データベースのマイグレーション、保存、取得を行いたいと考えています。

しかし、Entity Framework Coreはコードベースでデータベース操作できることが大きな機能なので、調査をしても、わざわざSQL文を発行しデータベース操作する情報がなかなか見つかりませんでした。


## 今回の記事の目的
今回の記事では
SQL文ベースでEntity Framework Coreを使用しどのようにデータベースマイグレーションを行うのか説明します。(とりあえずマイグレーション)

## 手順
今回は、Mysqlに対して接続する方法を記述します。

#### 1. 以下のパッケージをインストール

```
//ベースのパッケージ
Microsoft.EntityFrameworkCore

//コマンドを使うためのパッケージ
Microsoft.EntityFrameworkCore.Design

//EF coreを使用しMysqlに接続するためのパッケージ
MySql.EntityFrameworkCore
```

#### 2. dotnet ef コマンドを使えるか確認

dotnet ef --version

コマンドを打ちコマンドが使えるか確認してください。

#### 3. sqlファイル作成
それでは、sqlファイルをコマンドを打ち作成します。

```
dotnet ef migrations script -o Migrations/SqlScript.sql
```

```sql:SqlScript

//ここまデフォルト
CREATE TABLE IF NOT EXISTS `__EFMigrationsHistory` (
  `MigrationId` varchar(150) NOT NULL,
  `ProductVersion` varchar(32) NOT NULL,
  PRIMARY KEY (`MigrationId`)
);

//↓から個人の追加したテーブルを記述。(ここではusersテーブル)
CREATE TABLE IF NOT EXISTS users(
  id MEDIUMINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
  public_user_id VARCHAR(36) NOT NULL,
  email VARCHAR(255) NOT NULL,
  password VARCHAR(255) NOT NULL,
  name VARCHAR(32) NOT NULL,
  status enum("LEADER", "MEMBER") NOT NULL DEFAULT "MEMBER",
  created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  update_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
```

#### 4. DbContext周りの設定
プロジェクト内のどこでもいいので、

```c#
using Microsoft.EntityFrameworkCore;
namespace yourproject.foldername
{
  public class MyAppContext : DbContext
  {
    public MyAppContext(DbContextOptions<MyAppContext> options) : base(options) { }
  }
}
```

を作成

#### 5. Startup.csファイル編集

```c#
...略
    public void ConfigureServices(IServiceCollection services)
    {
      //4で作ったclassを挿入
      services.AddDbContext<MyAppContext>(options =>
      {
     //ここはご自身のmysql情報を挿入してください。(とりあえずベタ書き)
     options.UseMySQL("server=localhost;database=mysql;user=user;password=secret");
      });
      //mysqlの接続かつ1つのインスタンスを作成。
      services.AddSingleton<MysqlDb>();
      services.AddControllers();
    }
```

#### 6. Migration.csファイルを作成

```c#
using Microsoft.EntityFrameworkCore.Migrations;
using System.IO;
using Microsoft.EntityFrameworkCore.Infrastructure;
using teamev.api.infrastructure.db.db_context;
namespace yourproject.foldername
{
  [DbContext(typeof(MyAppContext))]
  [Migration("MigrationClass")]
  public partial class MigrationClass : Migration
  {
    protected override void Up(MigrationBuilder migrationBuilder)
    {
      //3で作成したsqlファイルを指定
      migrationBuilder.Sql(File.ReadAllText("Migration/SqlScript.sql"));

    }

    protected override void Down(MigrationBuilder migrationBuilder)
    {
      //説明してませんが、個人でテーブルを削除するなどのDrop.sqlファイルを作成
      migrationBuilder.Sql(File.ReadAllText("Migration/Drop.sql"));
    }
  }
}
```

#### 7. コマンドを打ちデータベースに反映
以下のコマンドで、6のUpメソッドが発火し、SqlScript.sqlファイル内のsql文が発火します。
マイグレーションしたい場合にこのコマンドを打ってください。

```
dotnet ef database update
```

以下のコマンドで、6のDownメソッドが発火します。
作成したテーブルを削除したい場合はこのコマンドを打ってください。

```
dotnet ef database update 0
```

#### 8. データベースに反映されているか確認
Mysqlのテーブル内を見て反映されているか確認してください。

## 最後に
これで、SQL文ファーストでマイグレーションを行うことができました。
.Net core初学者なので理解が甘い部分があると思うので、間違いなどありましたらコメントよろしくお願いします。