EF Code: первые миграции для развертывания старой версии

Я использую TFS Release Management для непрерывной интеграции и развертывания.

Я использую migrate.exe для выполнения миграции базы данных во время развертывания, и это прекрасно работает, когда вы переходите от более старой версии к более новой. Однако если вы хотите развернуть более старую версию приложения, она становится более мутной.

По сути, сборка, которая содержит ваши миграции для контекста, должна знать, как перейти от, скажем, версии 3 к версии 2. Обычно вы используете сборки, которые вы собираетесь развернуть, в качестве источника ваших миграций, но в этом случае вы должны используйте уже развернутые сборки, поскольку они единственные, кто знает, как перейти с v3 на v2. (Версия 2 понятия не имеет, что v3 даже существует.)

Мой текущий план состоит в том, чтобы как-то сравнить две сборки во время развертывания. Если сборка в каталоге установки содержит «более новые» миграции, чем в директории развертывания, мне сначала нужно получить «новейшую» доступную миграцию в сборке в каталоге развертывания, а затем выполнить:

migrate.exe AssemblyInInstallationDir /targetMigration NewestFromAssemblyInDeploymentDir

Где, как в «нормальном» сценарии развертывания, где вы обновляете до более новой версии, вы можете просто сделать:

migrate.exe AssemblyInDeploymentDir

Это законный подход? Мне еще предстоит изучить использование библиотек EF, чтобы оценить, какие миграции доступны в каждой сборке. Существует также проблема в том, что каждая из этих сборок представляет собой «одинаковые» просто разные версии. Вероятно, мне придется загрузить их в отдельные домены приложений, а затем использовать связи между доменами для получения необходимой информации.

РЕДАКТИРОВАТЬ

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

Приложение использует отражение для загрузки каждой сборки, а затем использует класс DbMigrator из System.Data.Entity.Migrations для перечисления метаданных миграции. Имена миграций начинаются с информации о метках времени, что позволяет мне упорядочить их и посмотреть, какая сборка содержит «более новый» набор миграций.

static void Main(string[] args)
{
    const string dllName = "Test.Data.dll";
    var assemblyCurrent = Assembly.LoadFile(Path.Combine(System.Environment.CurrentDirectory, string.Format("Current\\{0}", dllName)));
    var assemblyTarget = Assembly.LoadFile(Path.Combine(System.Environment.CurrentDirectory, string.Format("Target\\{0}", dllName)));

    Console.WriteLine("Curent Version: " + assemblyCurrent.FullName);
    Console.WriteLine("Target Version: " + assemblyTarget.FullName);

    const string contextName = "Test.Data.TestContext";
    const string migrationsNamespace = "Test.Data.Migrations";
    var currentContext = assemblyCurrent.CreateInstance(contextName);
    var targetContext = assemblyTarget.CreateInstance(contextName);

    var currentContextConfig = new DbMigrationsConfiguration
    {
        MigrationsAssembly = assemblyCurrent,
        ContextType = currentContext.GetType(),
        MigrationsNamespace = migrationsNamespace
    };

    var targetContextConfig = new DbMigrationsConfiguration
    {
        MigrationsAssembly = assemblyTarget,
        ContextType = targetContext.GetType(),
        MigrationsNamespace = migrationsNamespace
    };

    var migrator = new DbMigrator(currentContextConfig);
    var localMigrations = migrator.GetLocalMigrations(); //all migrations

    Console.WriteLine("Current Context Migrations:");
    foreach (var m in localMigrations)
    {
        Console.WriteLine("\t{0}", m);
    }

    migrator = new DbMigrator(targetContextConfig);
    localMigrations = migrator.GetLocalMigrations(); //all migrations

    Console.WriteLine("Target Context Migrations:");
    foreach (var m in localMigrations)
    {
        Console.WriteLine("\t{0}", m);
    }

    Console.ReadKey();
}

}

Вывод приложения выглядит так:

Curent Version: Test.Data, Version=1.3.0.0, Culture=neutral, PublicKeyToken=null
Target Version: Test.Data, Version=1.2.0.0, Culture=neutral, PublicKeyToken=null

Current Context Migrations:
    201403171700348_InitalCreate
    201403171701519_AddedAddresInfoToCustomer
    201403171718277_RemovedStateEntity
    201403171754275_MoveAddressInformationIntoContactInfo
    201403181559219_NotSureWhatIChanged
    201403181731525_AddedRowVersionToDomainObjectBase
Target Context Migrations:
    201403171700348_InitalCreate
    201403171701519_AddedAddresInfoToCustomer
    201403171718277_RemovedStateEntity

Ответы на вопрос(2)

Ваш ответ на вопрос