Я нашел способ указать, что моя база данных обновлена, и это (что неудивительно) основано на изменении таблицы __MigrationHistory
, которую миграция кода использует для определения того, какие миграции применять к БД при запуске Update-Database
.
Кстати, во время исследования этого ответа я наткнулся на очень хороший справочник по командам миграции кода, который можно найти по адресу: http://dotnet.dzone.com/articles/ef-migrations-command.
Когда база данных автоматически создается с нуля с помощью EF, она всегда будет помещать одну запись в таблицу __MigrationHistory
, и эта запись будет иметь MigrationId (currentDateTime)_InitialCreate
. Это представляет собой начальное создание базы данных, которое только что выполнил EF. Однако ваша история миграции не будет начинаться с этого MigrationId, потому что вы начали с чего-то другого.
Чтобы «обмануть» миграцию с первым кодом, заставив ее думать, что вы находитесь в последней миграции, вам нужно удалить эту запись (currentDateTime)_InitialCreate
из таблицы __MigrationHistory
вновь созданной БД и вставить то, что было бы там, если бы у вас все еще был старый БД, к которой были применены миграции.
Итак, сначала удалите все из недавно созданной таблицы __MigrationHistory
базы данных. Затем перейдите в консоль диспетчера пакетов и запустите:
PM> Update-Database -Script
Из получившегося SQL-скрипта вытащите все строки, начинающиеся с:
INSERT INTO [__MigrationHistory]...
Затем запустите эти операторы INSERT
в контексте только что созданной базы данных. Убедитесь, что каждая из этих строк теперь существует в вашей таблице __MigrationHistory
. При следующем запуске:
PM> Update-Database
... вы должны получить сообщение «Нет ожидающих миграций на основе кода». Поздравляем — вы обманули миграции кода, заставив их думать, что вы сейчас находитесь на последней миграции, и вы можете продолжить с того места, на котором остановились, добавляя новые миграции отсюда.
Я действительно думаю, что должен быть какой-то автоматизированный способ сделать это, встроенный в код EF, хотя... может быть, они должны добавить что-то вроде:
PM> Update-Database -MigrationsTableOnly
... в результате чего он уничтожит существующие записи в таблице миграций и просто вставит новые записи в историю миграций для каждой миграции, определенной в вашем проекте, но на самом деле не попытается запустить миграцию. Ах хорошо.
ОБНОВЛЕНИЕ
Я нашел способ хорошо автоматизировать это, используя метод Seed пользовательского инициализатора. По сути, метод Seed удаляет существующие данные истории миграции при создании БД и вставляет вашу историю миграции. В моем конструкторе контекста базы данных я регистрирую пользовательский инициализатор следующим образом:
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')");
}
}
person
Jez
schedule
28.10.2012
Update-Database -Force
? (это всего лишь дикая догадка) - person Jcl   schedule 27.10.2012