データベースが最新であることを示す方法を見つけました。これは (当然のことながら)__MigrationHistory
テーブルの変更に基づいており、実行時に DB に適用する移行を決定するためにコード ファースト マイグレーションが使用しますUpdate-Database
。
ところで、この回答を調査しているときに、コード ファーストの移行コマンドに関する非常に優れたリファレンスを見つけました。
データベースが EF によって自動的に最初から作成される場合、常に単一のエントリが__MigrationHistory
テーブルに配置され、そのエントリには MigrationId が含まれ(currentDateTime)_InitialCreate
ます。これは、EF が実行したばかりのデータベースの最初の作成を表します。ただし、移行履歴はその MigrationId で始まるわけではありません。別のことから始めているからです。
コードファーストの移行を「だまして」、最新の移行を行っていると思わせるには、新しく作成された DB(currentDateTime)_InitialCreate
のテーブルからそのエントリを削除し__MigrationHistory
、古い DB がまだあった場合にそこにあったであろうものを挿入する必要があります。移行が適用されていました。
したがって、最初に新しく生成された DB の__MigrationHistory
テーブルからすべてを削除します。次に、パッケージ マネージャー コンソールに移動し、次を実行します。
PM> Update-Database -Script
結果の SQL スクリプトから、次で始まるすべての行を取り出します。
INSERT INTO [__MigrationHistory]...
次に、INSERT
新しく作成されたデータベースのコンテキスト内でこれらのステートメントを実行します。これらの各行が__MigrationHistory
テーブルに存在することを確認します。次に実行するとき:
PM> Update-Database
...「保留中のコードベースの移行はありません」というメッセージが表示されるはずです。おめでとうございます - コード ファーストの移行をだまして、現在は最新の移行を行っていると思い込ませました。ここから新しい移行を追加して中断したところから続行できます。
EFコードファーストに組み込まれたこれを行う自動化された方法があるはずだと思いますが、おそらく次のようなものを追加する必要があります。
PM> Update-Database -MigrationsTableOnly
...これにより、移行テーブルの既存のエントリが上書きされ、プロジェクトで定義された移行ごとに新しいエントリが移行履歴に挿入されますが、実際に移行を試行して実行することはありません。まぁ。
更新
カスタム初期化子の Seed メソッドを使用して、これをうまく自動化する方法を見つけました。基本的に Seed メソッドは、DB の作成時に既存の移行履歴データを削除し、移行履歴を挿入します。私のデータベース コンテキスト コンストラクターでは、次のようにカスタム初期化子を登録します。
public class MyDatabaseContext : DbContext {
public MyDatabaseContext() : base() {
Database.SetInitializer(new MyDatabaseContextMigrationHistoryInitializer());
}
カスタム初期化子自体は次のようになります。
/// <summary>
/// This initializer clears the __MigrationHistory table contents created by EF code-first when it first
/// generates the database, and inserts all the migration history entries for migrations that have been
/// created in this project, indicating to EF code-first data migrations that the database is
/// "up-to-date" and that no migrations need to be run when "Update-Database" is run, because we're
/// already at the latest schema by virtue of the fact that the database has just been created from
/// scratch using the latest schema.
///
/// The Seed method needs to be updated each time a new migration is added with "Add-Migration". In
/// the package manager console, run "Update-Database -Script", and in the SQL script which is generated,
/// find the INSERT statement that inserts the row for that new migration into the __MigrationHistory
/// table. Add that INSERT statement as a new "ExecuteSqlCommand" to the end of the Seed method.
/// </summary>
public class MyDatabaseContextMigrationHistoryInitializer : CreateDatabaseIfNotExists<MyDatabaseContext> {
/// <summary>
/// Sets up this context's migration history with the entries for all migrations that have been created in this project.
/// </summary>
/// <param name="context">The context of the database in which the seed code is to be executed.</param>
protected override void Seed(MyDatabaseContext context) {
// Delete existing content from migration history table, and insert our project's migrations
context.Database.ExecuteSqlCommand("DELETE FROM __MigrationHistory");
context.Database.ExecuteSqlCommand("INSERT INTO __MigrationHistory (MigrationId, Model, ProductVersion) VALUES ('201210091606260_InitialCreate', 0x1F8B0800000000000400ECBD07601C499625262F6DCA7B7F4AF54AD7E074A..., '5.0.0.net40')");
context.Database.ExecuteSqlCommand("INSERT INTO __MigrationHistory (MigrationId, Model, ProductVersion) VALUES ('201210102218467_MakeConceptUserIdNullable', 0x1F8B0800000000000400ECBD07601C499625262F6DCA7B7F4..., '5.0.0.net40')");
context.Database.ExecuteSqlCommand("INSERT INTO __MigrationHistory (MigrationId, Model, ProductVersion) VALUES ('201210231418163_ChangeDateTimesToDateTimeOffsets', 0x1F8B0800000000000400ECBD07601C499625262F6D..., '5.0.0.net40')");
context.Database.ExecuteSqlCommand("INSERT INTO __MigrationHistory (MigrationId, Model, ProductVersion) VALUES ('201210251833252_AddConfigSettings', 0x1F8B0800000000000400ECBD07601C499625262F6DCA7B7F4AF54AD7E..., '5.0.0.net40')");
context.Database.ExecuteSqlCommand("INSERT INTO __MigrationHistory (MigrationId, Model, ProductVersion) VALUES ('201210260822485_RenamingOfSomeEntities', 0x1F8B0800000000000400ECBD07601C499625262F6DCA7B7F4AF5..., '5.0.0.net40')");
}
}