Использование Entity Framework (сначала код) миграции в производственной среде

Я просто изучаю возможность использования EF-миграции для нашего проекта и, в частности, для внесения изменений схемы в производственную среду между выпусками.

Я уже упоминал, что существует API для выполнения этих миграций во время выполнения с использованием класса DbMigration, но я не могу найти никаких конкретных примеров.

В идеале я хотел бы иметь один DbMigration файл для каждого изменения базы данных, и чтобы эти изменения применялись автоматически при запуске приложения с текущей версии до последней.


person devdigital    schedule 01.06.2012    source источник
comment
возможный дубликат Entity Framework 4.3 запускает миграции при запуске приложения   -  person Ladislav Mrnka    schedule 01.06.2012


Ответы (5)


Существует инициализатор базы данных, который вы можете использовать для перехода на последнюю версию при запуске (или лучше, dbinitializer сработает при первом доступе к базе данных), 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

person WDRust    schedule 01.06.2012
comment
Куда бы добавить этот код? Можно ли заключить это в условный оператор для проверки настройки приложения из файла web.config? чтобы при разработке этот код можно было пропустить? Тогда преобразования web.config включат его при публикации выпущенной версии? - person Doug Chamberlain; 24.06.2013
comment
Если вам нужно установить инициализатор условно для свойств конфигурации, лучше использовать функцию EF4.3. См. Эту статью msdn.microsoft.com/en-US/data/jj556606 (Часть инициализатора базы данных), используйте это вместе с преобразованием, и вы настроены - person WDRust; 24.06.2013
comment
Подробнее об этом здесь: msdn.microsoft.com/en-us/ data / jj591621.aspx # initializer И для тех из вас, кто опасается автоматических миграций и обновлений схемы базы данных и считает, что ручное редактирование сценария безопаснее ... убедитесь, что у вас есть резервная копия, и сначала проверьте ее Ради бога!! - person Bron Davies; 19.01.2016
comment
Я расширил эту тему при обновлении этого вопроса, экспертная оценка приветствуется - person WDRust; 09.05.2016
comment
Это решение подразумевает, что у приложения есть разрешения на изменение схемы. Я думаю, что это маловероятно в производственной среде, где приложение ограничено только манипуляциями с данными. Интересно, можно ли запускать миграции из скомпилированной DLL, используя интерфейс командной строки dotnet (из учетной записи администратора или путем предоставления учетных данных) - person Assaf S.; 04.04.2019

Это тоже работает:

var configuration = new MyDbContextConfiguration();
configuration.TargetDatabase = new DbConnectionInfo(
    database.ConnectionString, database.ProviderName);

var migrator = new DbMigrator(configuration);
migrator.Update();

Вы также можете позвонить:

migrator.GetPendingMigrations();

чтобы получить список необходимых миграций.

person mackie    schedule 06.08.2012
comment
Что это за переменная database? - person d512; 14.07.2014
comment
В этом случае просто DTO со свойствами ConnectionString и ProviderName. Это не часть структуры. - person mackie; 15.07.2014
comment
Если я использую этот метод, какой инициализатор мне следует использовать для создания dbContext? - person John Shedletsky; 19.02.2015
comment
В конструкторе DbContext просто выполните: Database.SetInitializer ‹TypeOfMyDbContext› (null); - person mackie; 20.02.2015
comment
У меня это сработало, даже если убрать часть new DbConnectionInfo. Спасибо! - person Alejandro B.; 06.02.2018

Поскольку вы не указали, какую версию Visual Studio вы используете или базу данных, я добавлю здесь ответ, чтобы сказать, что в VS2015 с Microsoft SQL Server теперь это невероятно просто с помощью инструмента «Опубликовать».

Вам не нужно беспокоиться о API, о котором вы говорите. Просто выполняйте свою работу локально, меняя свои модели, применяя миграции и т. Д., А затем, когда вы хотите продвинуться на серверы выпуска / тестирования, используйте инструмент публикации.

Вы можете применить любые миграции, которые вы сделали локально, к удаленному серверу при первом запуске приложения.

После того, как у вас есть все миграции и все сделано локально (предположительно в среде разработки), вы публикуете (щелкните проект правой кнопкой мыши, выберите «Опубликовать ...». Установите флажок «Выполнить первые миграции кода (запускается при запуске приложения)» под вкладка «Настройки», а затем он применит миграции при первом доступе к приложению (поэтому в первый раз будет небольшая задержка).

«Публикация

Руководство: 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/

Удачи!

person Worthy7    schedule 03.06.2016
comment
Просто расширенный комментарий, так как я стал старше и мудрее. Обычно вы не хотите автоматически выполнять миграции на рабочем сервере. В идеале вы создаете сценарий SQL для выполнения миграции, проверяете, выполняет ли он то, что вы хотите, а затем запускаете сценарий в производственной базе данных во время публикации / развертывания приложения. Это стандартный способ сделать это. - person Worthy7; 14.08.2020
comment
Это недоступно при публикации на File System - person MohammadHossein R; 14.09.2020

Я хотел контролировать, какие миграции выполняются явно в коде, и после долгого поиска мне удалось разработать следующий метод без необходимости использования класса 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);
}

С Уважением.

person Panos Roditakis    schedule 13.01.2016

Чтобы добавить ко всем уже опубликованным ответам. 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 запускает миграции, которые еще не были применены к базе данных.

person LuTheZy    schedule 20.06.2019