tfs - EF Code First 迁移以部署旧版本

标签 tfs ef-code-first entity-framework-migrations release-management ms-release-management

我正在使用 TFS 发布管理进行持续集成和部署。

我在部署期间使用 migrate.exe 执行数据库迁移,当您从旧版本升级到新版本时,这非常有用。但是,当您想要部署旧版本的应用程序时,它会变得更加困惑。

基本上,为上下文保存迁移的程序集必须知道如何从版本 3 转到版本 2。通常,您使用要部署的程序集作为迁移的源,但在这种情况下,您必须使用已经部署的程序集,因为它们是唯一知道如何从 v3 到 v2 的程序集。 (版本 2 甚至不知道 v3 存在。)

我目前的计划是在部署期间以某种方式比较这两个程序集。如果安装目录中的程序集包含比部署目录中的“更新”迁移,我首先需要在部署目录中的程序集中获取“最新”可用迁移,然后执行:

migrate.exe AssemblyInInstallationDir /targetMigration NewestFromAssemblyInDeploymentDir

在升级到较新版本的“正常”部署场景中,您可以这样做:
migrate.exe AssemblyInDeploymentDir

这是一种合法的方法吗?我还没有考虑使用 EF 库来评估每个程序集中可用的迁移。还有一个挑战是这些程序集中的每一个都是“相同的”只是不同的版本。我可能必须将它们加载到单独的应用程序域中,然后使用跨应用程序域通信来获取我需要的信息。

编辑

我创建了一个概念验证应用程序,它允许我列出对同一程序集的两个不同版本的可用迁移。这对整个过程至关重要,所以我认为值得记录。

该应用程序使用反射来加载每个程序集,然后使用 System.Data.Entity.Migrations 中的 DbMigrator 类来枚举迁移元数据。迁移的名称以时间戳信息为前缀,因此我可以对它们进行排序并查看哪个程序集包含“较新”的迁移集。
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

最佳答案

我们实际上解决了这个问题,并且已经使用我们的工具一年多来将完全连续的数据库部署到生产环境中。没有人类参与。 :)

我们在 GitHub 上公开了其中的一些内容:https://github.com/GalenHealthcare/Galen.Ef.Deployer

您可以进行“重大”更改,但通常我们也会避免这种情况——但主要是因为我们的应用程序在升级期间仍然有效。我们将数据层视为可独立部署的组件 - 因此,它具有需要保持兼容的“接口(interface)”。

我们经常使用多阶段升级方法,部署一个向后/向前兼容的中间版本,升级我们的各种应用程序服务,然后最后升级数据库层以消除遗留兼容性。

即使在这种情况下,我们也有能力自动进出我们的架构和数据的任何版本。事实上,我们已经添加了单元测试,每次我们为每个数据库版本构建时都会验证这一点。它基本上沿着模式迭代链向上/向下走,并验证向上和向下迁移始终有效并保持数据一致性和兼容性。您可以在 GitHub 项目中看到这些测试。这是一个例子:

https://github.com/GalenHealthcare/Galen.Ef.Deployer/blob/master/Galen.Ci.EntityFramework.Deployer/Galen.Ci.EntityFramework.Testing/MigrationTestRunner.cs

关于tfs - EF Code First 迁移以部署旧版本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22765527/

相关文章:

tfs - 在 TFS Build 中运行 Specflow 测试

c# - 我可以在 EF 中播种所需属性的数据吗?

azure - 数据库部署作为 azure 持续部署的一部分

visual-studio-2012 - 团队基础错误无法加载文件或程序集 Microsoft.Practices.EnterpriseLibrary.Common

tfs - 如何将 Visual Studio 2019 连接到 TFS?

sql - Entity Framework 4 Code First 出现数据库使用错误

asp.net-mvc - EF 4.5 Code First 复合键的 MVC 脚手架错误

c# - 如何从代码 (EF Core) 应用迁移

c# - 没有默认数据库时的 Entity Framework 6 和迁移

c# - 使用 Entity Framework 在代码优先迁移中有条件地插入数据