こんにちは、あおいです。
今年の初詣は大須観音に行ってきました!引いたおみくじが大吉!幸先のよいスタートです!
さて、EF Coreを用いたCode First開発は非常に便利です。
以下のコマンド実行をすると、[Migrations]ディレクトリの下で3つのファイルがプロジェクトに自動生成されます。
dotnet ef migrations add <Migration名>
- XXXXX_AddCreatedAt.cs -- 移行コード
- XXXXX_AddCreatedAt.Designer.cs -- 移行のメタデータファイル
- DbContextModelSnapshot.cs -- 現在のモデルのスナップショット
以下のコマンドを実行すると、移行コードの内容がDBに適用されます。
dotnet ef database update
ここで大事なのが、移行コードの中身をきちんと確認しないと爆死事故が起きます。
その事故を回避するには、移行コードをスクラッチでカスタマイズする必要があります。
そこで、今回はEntity Framework Core で移行コードをカスタマイズする方法について紹介したいと思います。
例として列名(Name⇒FullName)と桁数(10⇒15)を変更すると、EF Core によって次の移行が生成されます。
Upメソッドは変更の差分をDBに適用し、Downメソッドは変更の差分を元に戻したい時に呼ばれるメソッドです。
C#using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace EFCoreSample.Migrations
{
public partial class second : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "Name",
table: "Employees");
migrationBuilder.AddColumn<string>(
name: "FullName",
table: "Employees",
type: "nvarchar(15)",
nullable: false,
defaultValue: "");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "FullName",
table: "Employees");
migrationBuilder.AddColumn<string>(
name: "Name",
table: "Employees",
type: "nvarchar(10)",
nullable: false,
defaultValue: "");
}
}
}
ここで注意しなければならない点は、上記のファイル(移行コード)をそのままマイグレーションで適用すると、既存のNameカラムにあったデータが全て失われてしまうことです。
また、列の順番も変わってしまい、元に戻そうとDownを適用(ロールバック)してもデータは復元されません。
理由はDropColumn(列を削除)して、AddColumn(新しい列を作成)するからです。そのまんまの意味です。
列を新規追加する場合は問題ないですが、既存の列定義を変更しただけで既存のデータが全部消えるのは避けたいですよね。
解決策として、以下のように移行コードをスクラッチでカスタマイズする必要があります。
C#using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace EFCoreSample.Migrations
{
public partial class second : Migration
{
// dotnet ef database updateでUpメソッドが適用される
protected override void Up(MigrationBuilder migrationBuilder)
{
// 列の名前を変更して
migrationBuilder.RenameColumn(
name: "Name",
table: "Employees",
newName: "FullName");
// 文字列長等の定義を変更する
migrationBuilder.AlterColumn<string>(
name: "FullName",
table: "Employees",
type: "nvarchar(15)",
nullable: false,
defaultValue: "",
oldType: "nvarchar(10)",
oldClrType: typeof(string));
}
// dotnet ef database update <Migration名>のロールバックでDownメソッドが適用される
protected override void Down(MigrationBuilder migrationBuilder)
{
// 列の名前を元に戻して
migrationBuilder.RenameColumn(
name: "FullName",
table: "Employees",
newName: "Name");
// 文字列等の定義を元に戻す
migrationBuilder.AlterColumn<string>(
name: "Name",
table: "Employees",
type: "nvarchar(10)",
nullable: false,
defaultValue: "",
oldType: "nvarchar(15)",
oldClrType: typeof(string));
}
}
}
MigrationBuilderクラスのメソッド一覧 | Microsoft Docs
データが失われる場合、以下の緑色の警告文が表示されます。こいつが表示されたら要注意なので、移行コードをきちんと確認するようにしましょう。
また、組み込みAPIが使用不可の場合、生SQL操作を導入します。
詳細についてはこちらの記事をご覧ください。
今回はEntity Framework Coreで移行コードをカスタマイズする方法について紹介させていただきました。
PK定義の変更をする場合も、移行コードをスクラッチでカスタマイズする必要がありますが、次回の記事で紹介します。
Entity Framework CoreでPK定義の変更をする方法 | cloud.config Tech Blog
参考記事
移行コードをカスタマイズする - EF Core | Microsoft Docs