【C#】ASP.NET Core の DB マイグレーションでテーブル定義の変更やテーブルを削除をする方法

##はじめに

タイトルの通り、ASP.NET Core の データベースマイグレーション機能で

- テーブル定義の変更
- テーブルの削除

を行います。

最新の .NET Core SDK には EF Core のランタイムが統合されているため、dotnet CLI からマイグレーションの操作が可能です。
 


## サンプルのデータベースの作成

- テーブル定義の変更やテーブル削除の対象となるデータベースを作成します。
- ローカルで動く簡易 DB である SQL Server LocalDB を使用します。

```sh
dotnet --version
2.1.400
## プロジェクトの作成
dotnet new web -o AlterDeleteTableSample
cd AlterDeleteTableSample
```

- エンティティとデータベースコンテキストは以下の通りを作成しました。
- カードゲームを想定します。

```cs:Models.cs
using Microsoft.EntityFrameworkCore;

namespace AlterDeleteTableSample
{
    public class Card
    {
        public int ID { get; set; }
        public string Title { get; set; }
        public string Type { get; set; }
    }

    public class CardGameContext : DbContext
    {
        public CardGameContext(DbContextOptions options)
            : base(options) { }

        public DbSet<Card> Cards { get; set; }
    }
}
```

- プロジェクトのルートにある`Startup.cs`で接続文字列を定義します。

```cs:Startup.cs
public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<CardGameContext>(options =>
    {
        options.UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=CardGame;Trusted_Connection=True;");
    });
}
```

- マイグレーションファイルをスキャフォールディングし、データベースを生成します。

```sh
dotnet ef migrations add  InitialCreate
dotnet ef database update
```

テーブルを SQL Server オブジェクトエクスプローラーで確認します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/195024/95093caf-b5b0-fb5e-6748-97ad1069f663.png)


## テーブル定義の変更

**カードタイトルを必須**にし、**カードパワーも追加**してみます。
`Model.cs`の`Card`クラスを以下のように編集します。

```cs:
using Microsoft.EntityFrameworkCore;
using System.ComponentModel.DataAnnotations;

namespace AlterDeleteTableSample
{
    public class Card
    {
        public int ID { get; set; }
        [Required]
        public string Title { get; set; }
        public string Type { get; set; }
        public int Power { get; set; }
    }
    /* 略 */
}
```

マイグレーションファイルをスキャフォールディングします。

```sh
dotnet ef migrations add Second
```

`An operation was scaffolded that may result in the loss of data. Please review the migration for accuracy.`と警告が出ますが、レコードがテーブルに無いので気にしなくて OK です。


マイグレーションファイルの内容を確認すると移行内容が書かれています。

```cs:
using Microsoft.EntityFrameworkCore.Migrations;

namespace AlterDeleteTableSample.Migrations
{
    public partial class Second : Migration
    {
        protected override void Up(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.AlterColumn<string>(
                name: "Title",
                table: "Cards",
                nullable: false,
                oldClrType: typeof(string),
                oldNullable: true);

            migrationBuilder.AddColumn<int>(
                name: "Power",
                table: "Cards",
                nullable: false,
                defaultValue: 0);
        }

        protected override void Down(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.DropColumn(
                name: "Power",
                table: "Cards");

            migrationBuilder.AlterColumn<string>(
                name: "Title",
                table: "Cards",
                nullable: true,
                oldClrType: typeof(string));
        }
    }
}
```

マイグレーションファイルを適用しテーブル定義を変更します。

```sh
dotnet ef database update
```

SQL Server オブジェクトエクスプローラーから確認すると`Cards`テーブルの内容が変更されているのが確認できます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/195024/d69ac5d4-c76c-dc49-ee4b-cae975fd8867.png)

## テーブルの削除

テーブルを削除するには**データベースコンテキストの`DbSet<TEntity>`を削除**します。

```diff
    using Microsoft.EntityFrameworkCore;
    using System.ComponentModel.DataAnnotations;

    namespace AlterDeleteTableSample
    {
        public class Card
        {
            public int ID { get; set; }
            [Required]
            public string Title { get; set; }
            public string Type { get; set; }
            public int Power { get; set; }
        }

        public class CardGameContext : DbContext
        {
            public CardGameContext(DbContextOptions options)
                : base(options) { }

-           public DbSet<Card> Cards { get; set; }
        }
    }
```

- マイグレーションファイルをスキャフォールディングします。
- テーブル定義の変更した時と同じ警告が出ますが、失うレコードは無いので無視します。

```sh
dotnet ef migrations add DropCardsTable
```

- データベースに変更を適用します。

```sh
dotnet ef database update
```

`dbo.Cards`テーブルが削除されています。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/195024/bb2eb142-f9bc-4bb7-8221-b92aa98f14cf.png)

## 追記

不要なスキーマを削除する場合、SQL Server オブジェクトエクスプローラーで
`スキーマを右クリック > 削除 > 「既存の接続を閉じる」をチェック > OK` で削除できます。

___


- SI 企業所属の2年目プログラマーです。 
- 普段はオンプレミスの基幹システムの開発をしていますが、Web 技術も大好きです。
- エンジニアの方と繋がれると、とてもうれしいです。

**twitter: [のさ@nosa_programmer](https://twitter.com/nosa_programmer)**