移行の管理Managing Migrations

モデルが変更されると、通常の開発の一環として移行が追加および削除され、移行ファイルがプロジェクトのソース管理にチェックインされます。As your model changes, migrations are added and removed as part of normal development, and the migration files are checked into your project's source control. 移行を管理するには、まず EF Core コマンドラインツールをインストールする必要があります。To manage migrations, you must first install the EF Core command-line tools.

ヒント

DbContext がスタートアップ プロジェクトとは異なるアセンブリに含まれている場合、ターゲットとスタートアップ プロジェクトはパッケージ マネージャー コンソール ツールまたは .NET Core CLI ツールのいずれかに明示的に指定できます。If the DbContext is in a different assembly than the startup project, you can explicitly specify the target and startup projects in either the Package Manager Console tools or the .NET Core CLI tools.

移行を追加するAdd a migration

モデルが変更されたら、その変更の移行を追加できます。After your model has been changed, you can add a migration for that change:

dotnet ef migrations add AddBlogCreatedTimestamp

移行名は、バージョン管理システムのコミット メッセージのように使用できます。The migration name can be used like a commit message in a version control system. たとえば、変更がエンティティの新しいプロパティである場合、 Addブログ のような名前を選択でき CreatedTimestamp Blog ます。For example, you might choose a name like AddBlogCreatedTimestamp if the change is a new CreatedTimestamp property on your Blog entity.

[移行] ディレクトリの下で 3 つのファイルがプロジェクトに追加されます。Three files are added to your project under the Migrations directory:

  • XXXXXXXXXXXXXX_AddCreatedTimestamp、メインの移行ファイルです。XXXXXXXXXXXXXX_AddCreatedTimestamp.cs--The main migrations file. (Up で) 移行を適用し、(Down で) それを元に戻すために必要な操作が含まれます。Contains the operations necessary to apply the migration (in Up) and to revert it (in Down).
  • XXXXXXXXXXXXXX_AddCreatedTimestamp、移行メタデータファイルです。XXXXXXXXXXXXXX_AddCreatedTimestamp.Designer.cs--The migrations metadata file. EF によって使用される情報が含まれます。Contains information used by EF.
  • MyContextModelSnapshot.cs--現在のモデルのスナップショット。MyContextModelSnapshot.cs--A snapshot of your current model. 次の移行を追加するときの変更内容の決定に使用されます。Used to determine what changed when adding the next migration.

変更の進行がわかるように、ファイル名のタイムスタンプは時系列順で維持されます。The timestamp in the filename helps keep them ordered chronologically so you can see the progression of changes.

名前空間Namespaces

移行ファイルは自由に移動し、手動で名前空間を変更できます。You are free to move Migrations files and change their namespace manually. 新しい移行は前回の移行の兄弟として作成されます。New migrations are created as siblings of the last migration. または、次のように、生成時に名前空間を指定することもできます。Alternatively, you can specify the namespace at generation time as follows:

dotnet ef migrations add InitialCreate --namespace Your.Namespace

移行コードをカスタマイズするCustomize migration code

EF Core 通常は正確な移行を作成しますが、コードを常に確認し、必要な変更に対応していることを確認してください。場合によっては、これを行う必要もあります。While EF Core generally creates accurate migrations, you should always review the code and make sure it corresponds to the desired change; in some cases, it is even necessary to do so.

列名の変更Column renames

移行のカスタマイズが必要な例の1つは、プロパティの名前を変更する場合です。One notable example where customizing migrations is required is when renaming a property. たとえば、プロパティの名前をからに変更すると Name FullName 、EF Core によって次の移行が生成されます。For example, if you rename a property from Name to FullName, EF Core will generate the following migration:

migrationBuilder.DropColumn(
    name: "Name",
    table: "Customers");

migrationBuilder.AddColumn<string>(
    name: "FullName",
    table: "Customers",
    nullable: true);

EF Core は、通常、列を削除し、新しい列 (2 つの異なる変更) を作成し、列の名前を変更する必要があるかどうかを知ることができません。EF Core is generally unable to know when the intention is to drop a column and create a new one (two separate changes), and when a column should be renamed. 上記の移行がそのように適用されている場合、顧客名はすべて失われます。If the above migration is applied as-is, all your customer names will be lost. 列の名前を変更するには、上記の生成された移行を次のように置き換えます。To rename a column, replace the above generated migration with the following:

migrationBuilder.RenameColumn(
    name: "Name",
    table: "Customers",
    newName: "FullName");

ヒント

移行のスキャフォールディング手順では、(列の削除など) データが失われる場合に、警告が出ます。The migration scaffolding process warns when an operation might result in data loss (like dropping a column). その警告が表示されたら、移行コードが正しいことを特に確認してください。If you see that warning, be especially sure to review the migrations code for accuracy.

生の SQL の追加Adding raw SQL

列の名前の変更は、組み込みの API を使用して行うことができますが、多くの場合、可能ではありません。While renaming a column can be achieved via a built-in API, in many cases that is not possible. たとえば、既存の FirstName LastName プロパティとプロパティを1つの新しいプロパティに置き換えることができ FullName ます。For example, we may want to replace existing FirstName and LastName properties with a single, new FullName property. EF Core によって生成される移行は、次のようになります。The migration generated by EF Core will be the following:

migrationBuilder.DropColumn(
    name: "FirstName",
    table: "Customer");

migrationBuilder.DropColumn(
    name: "LastName",
    table: "Customer");

migrationBuilder.AddColumn<string>(
    name: "FullName",
    table: "Customer",
    nullable: true);

以前と同様に、望ましくないデータ損失が発生します。As before, this would cause unwanted data loss. 古い列からデータを転送するには、次のように移行を再配置し、生の SQL 操作を導入します。To transfer the data from the old columns, we rearrange the migrations and introduce a raw SQL operation as follows:

migrationBuilder.AddColumn<string>(
    name: "FullName",
    table: "Customer",
    nullable: true);

migrationBuilder.Sql(
@"
    UPDATE Customer
    SET FullName = FirstName + ' ' + LastName;
");

migrationBuilder.DropColumn(
    name: "FirstName",
    table: "Customer");

migrationBuilder.DropColumn(
    name: "LastName",
    table: "Customer");

未加工の SQL を使用した任意の変更Arbitrary changes via raw SQL

生の SQL を使用すると、EF Core 認識されないデータベースオブジェクトを管理することもできます。Raw SQL can also be used to manage database objects that EF Core isn't aware of. これを行うには、モデルを変更せずに移行を追加します。空の移行が生成されます。その後、生の SQL 操作を設定できます。To do this, add a migration without making any model change; an empty migration will be generated, which you can then populate with raw SQL operations.

たとえば、次の移行では、SQL Server のストアドプロシージャが作成されます。For example, the following migration creates a SQL Server stored procedure:

migrationBuilder.Sql(
@"
    EXEC ('CREATE PROCEDURE getFullName
        @LastName nvarchar(50),
        @FirstName nvarchar(50)
    AS
        RETURN @LastName + @FirstName;')");

これを使用すると、次のようなデータベースのあらゆる側面を管理できます。This can be used to manage any aspect of your database, including:

  • ストアド プロシージャStored procedures
  • フルテキスト検索Full-Text Search
  • 関数Functions
  • トリガーTriggers
  • ビューViews

ほとんどの場合、移行を適用すると、EF Core によって各移行が独自のトランザクションで自動的にラップされます。In most cases, EF Core will automatically wrap each migration in its own transaction when applying migrations. 残念ながら、一部のデータベースでは、一部の移行操作をトランザクション内で実行することはできません。このような場合は、に渡すことによってトランザクションをオプトアウトすることができ suppressTransaction: true migrationBuilder.Sql ます。Unfortunately, some migrations operations cannot be performed within a transaction in some databases; for these cases, you may opt out of the transaction by passing suppressTransaction: true to migrationBuilder.Sql.

DbContext がスタートアップ プロジェクトとは異なるアセンブリに含まれている場合、ターゲットとスタートアップ プロジェクトはパッケージ マネージャー コンソール ツールまたは .NET Core CLI ツールのいずれかに明示的に指定できます。If the DbContext is in a different assembly than the startup project, you can explicitly specify the target and startup projects in either the Package Manager Console tools or the .NET Core CLI tools.

移行を削除するRemove a migration

移行の追加後、適用する前に EF Core モデルの追加変更が必要なことに気付く場合があります。Sometimes you add a migration and realize you need to make additional changes to your EF Core model before applying it. 最後の移行を削除するには、このコマンドを使用します。To remove the last migration, use this command.

dotnet ef migrations remove

移行の削除後、追加のモデル変更を行い、もう一度追加できます。After removing the migration, you can make the additional model changes and add it again.

警告

実稼働データベースに既に適用されている移行は削除しないように注意してください。Take care not to remove any migrations which are already applied to production databases. そうしないと、それを元に戻すことができなくなり、その後の移行によって想定される内容が壊れる可能性があります。Not doing so will prevent you from being able to revert it, and may break the assumptions made by subsequent migrations.

移行の一覧表示Listing migrations

次のように、すべての既存の移行を一覧表示できます。You can list all existing migrations as follows:

dotnet ef migrations list

すべての移行をリセットしていますResetting all migrations

極端なケースでは、すべての移行を削除してからやり直すことが必要になる場合があります。In some extreme cases, it may be necessary to remove all migrations and start over. これは、 移行 フォルダーを削除して、データベースを削除することで簡単に行うことができます。この時点で、新しい初期移行を作成できます。これには、現在のスキーマ全体が含まれます。This can be easily done by deleting your Migrations folder and dropping your database; at that point you can create a new initial migration, which will contain you entire current schema.

すべての移行をリセットし、データを失うことなく1つの移行を作成することもできます。It's also possible to reset all migrations and create a single one without losing your data. これは "スカッシュ" と呼ばれることもあり、手動での作業が必要です。This is sometimes called "squashing", and involves some manual work:

  • マイグレーションフォルダーの削除Delete your Migrations folder
  • 新しい移行を作成し、その移行用の SQL スクリプトを生成するCreate a new migration and generate a SQL script for it
  • データベースで、移行履歴テーブルからすべての行を削除します。In your database, delete all rows from the migrations history table
  • 1つの行を移行履歴に挿入して、最初の移行が既に適用されていることを記録します。これは、テーブルが既に存在しているためです。Insert a single row into the migrations history, to record that the first migration has already been applied, since your tables are already there. Insert SEQL は、上記で生成された SQL スクリプトの最後の操作です。The insert SEQL is the last operation in the SQL script generated above.