Использование миграции Entity Framework (сначала кода) при производстве
Я просто изучаю использование EF-миграций для нашего проекта и, в частности, для выполнения изменений схемы в производстве между выпусками.
Я уже упоминал, что для выполнения этих миграций во время выполнения существует API, использующий класс DbMigration
, но я не могу найти конкретных примеров.
В идеале я хотел бы получить один файл DbMigration
для каждого изменения базы данных и для тех изменений, которые будут применяться автоматически при запуске приложения с текущей версии до последней версии.
Ответы
Ответ 1
Существует Инициализатор базы данных, который вы можете использовать для перехода к последней версии при запуске (или, лучше, dbinitializer будет использовать первый доступ к db), MigrateDatabaseToLatestVersion
, вы используете его следующим образом:
Database.SetInitializer<ObjectContext>(
new MigrateDatabaseToLatestVersion<ObjectContext, Configuration>());
Относительно наличия одного файла на перенос, если вы включите автоматическую миграцию, вы найдете их в папке Migrations
(по умолчанию) в корневом каталоге вашего проекта.
Релевантная информация, с примерами, здесь: http://weblogs.asp.net/fredriknormen/archive/2012/02/15/using-entity-framework-4-3-database-migration-for-any-project.aspx
Ответ 2
Это тоже работает:
var configuration = new MyDbContextConfiguration();
configuration.TargetDatabase = new DbConnectionInfo(
database.ConnectionString, database.ProviderName);
var migrator = new DbMigrator(configuration);
migrator.Update();
Вы также можете позвонить:
migrator.GetPendingMigrations();
чтобы получить список необходимых им миграций.
Ответ 3
Поскольку вы не указали, какую версию Visual Studio вы используете, или Database, я добавлю здесь ответ, чтобы сказать, что в VS2015 с Microsoft SQL Server это теперь невероятно легко, используя инструмент "Опубликовать".
Вам не нужно беспокоиться об API, о котором вы говорите. Просто выполняйте свою работу на местном уровне, меняя свои модели, применяя миграции и т.д., А затем, когда вы хотите выйти на сервер выпуска/тестирования, используйте инструмент публикации.
Вы можете применить любые миграции, которые вы сделали локально, к удаленному серверу при первом запуске приложения.
Как только у вас есть все ваши миграции и все, что сделано локально (предположительно в вашем Dev env), вы публикуете (щелкните правой кнопкой мыши проект, нажмите "Опубликовать..." Отметьте "Выполнять первые шаги миграции кода (запускается при запуске приложения)" на вкладке "Настройки", а затем он применит миграцию при первом обращении к приложению (так что в первый раз будет небольшая задержка).
![Публиковать веб-интерфейс с помощью Web-Deploy]()
Руководство:
https://msdn.microsoft.com/en-us/library/dd465337(v=vs.110).aspx
Я узнал все это, потому что я должен был сделать это на сервере Windows 2012:
http://www.sherweb.com/blog/how-to-install-webdeploy-on-windows-server-2012/
Удачи!
Ответ 4
Я хотел бы контролировать, какие миграции выполняются явно в коде, и после большого поиска мне удалось разработать следующий метод без необходимости включения класса DbConfiguration или автоматических миграций:
public static void RunMigration(this DbContext context, DbMigration migration)
{
var prop = migration.GetType().GetProperty("Operations", BindingFlags.NonPublic | BindingFlags.Instance);
if (prop != null)
{
IEnumerable<MigrationOperation> operations = prop.GetValue(migration) as IEnumerable<MigrationOperation>;
var generator = new SqlServerMigrationSqlGenerator();
var statements = generator.Generate(operations, "2008");
foreach (MigrationStatement item in statements)
context.Database.ExecuteSqlCommand(item.Sql);
}
}
И если бы у нас была такая миграция:
public class CreateIndexOnContactCodeMigration : DbMigration
{
public override void Up()
{
this.CreateIndex("Contacts", "Code");
}
public override void Down()
{
base.Down();
this.DropIndex("Contacts", "Code");
}
}
Мы будем использовать его так:
using (var dbCrm = new CrmDbContext(connectionString))
{
var migration = new CreateIndexOnContactCodeMigration();
migration.Up();
dbCrm.RunMigration(migration);
}
С уважением.
Ответ 5
Чтобы добавить ко всем ответам уже размещены. Entity Framework использует таблицу: dbo.__ MigrationHistory для отслеживания всех миграций, которые уже применены к базе данных, чтобы избежать запуска миграции, которая, например: вставляет данные или изменяет схему базы данных.
Если вы хотите запустить сценарий, например запустить добавление данных или изменить схему базы данных, вы можете создать пустую миграцию с помощью консоли диспетчера пакетов и запустить сценарий с помощью новой добавленной миграции. Убедитесь, что вы используете инициализатор, чтобы EF не сбрасывал и не воссоздавал базу данных при каждом запуске.
public override void Up()
{
string directoryToSearchScripts = Path.GetFullPath(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "..\\..\\"));
string scriptFilePath = Directory.GetFiles(directoryToSearchScripts, "dummy-script.sql", SearchOption.AllDirectories).FirstOrDefault();
if (!string.IsNullOrEmpty(scriptFilePath))
{
string fundsSqlScript = File.ReadAllText(scriptFilePath);
Sql(fundsSqlScript);
}
}
public override void Down()
{
}
Когда вы опубликуете приложение и отметите опцию "Выполнить первые миграции кода", EF запустит миграции, которые еще не применены к базе данных.