我有一个简单的网络应用程序。它由一个Azure Web应用程序和分阶段和生产槽组成。当没有DB迁移需要考虑时,我可以很容易地通过以下方法实现无缝更新:
当我需要处理DB迁移时,这就变得更加棘手了。现在我要做的是:
这意味着我仍然有效地有停机时间,因为2+3不会同时发生,这意味着在几秒钟内,随着'DB模式的改变‘,我的用户将体验到不完美的行为。
这里最简单的解决办法是什么?我在想,我可能也必须分拆一个暂存数据库,但接下来我不得不担心复制和连接字符串管理,这会增加一些开销。
发布于 2016-07-30 08:50:34
当我们将解决方案转移到连续交付模型时,我们也遇到了同样的困境,我们希望避免停机。
您需要将EF配置为首先在开发环境和数据库上运行代码。
这使得将您的更改分为三个阶段成为可能:
第1阶段.数据库迁移
在这个阶段,您将使用EF的migrate.exe实用程序(或者直接手工编写脚本)来对活动数据库运行最新的迁移。在迁移应用之后,您的网站在生产中仍然保持功能,因为什么都没有发生(因为它被配置为数据库优先)。
重要的位是,您需要确保在此阶段的迁移是可加性的,也就是说,它将更改一个表或列,这将导致活动站点崩溃。它可能看起来很可怕,但是如果您的项目已经足够成熟,您很快就会意识到,对您的模式的大多数更改要么是完全可加的,要么可以分为两个阶段。(见第3阶段)
第二阶段:更新制作网站
在这个阶段做你的正常阶段->生产网站的部署。
第三阶段:数据库迁移(第二部分)
在一些罕见的情况下,例如重命名了数据库表或列,您需要考虑将其分解为以下两个步骤:
附录
EF数据库-只在生产中第一
在Startup.cs或Global.asax.cs中
#if DEBUG
Database.SetInitializer(new MigrateDatabaseToLatestVersion<AppDatabase, Migrations.Migrations.Configuration>());
#else
Database.SetInitializer(new RequireDatabaseToBeUpToDate<AppDatabase, Migrations.Migrations.Configuration>());
#endif这正是它在罐头上说的:
public class RequireDatabaseToBeUpToDate<TContext, TMigrationsConfiguration> : IDatabaseInitializer<TContext>
where TContext : DbContext
where TMigrationsConfiguration : DbMigrationsConfiguration, new()
{
public void InitializeDatabase(TContext context)
{
var migrator = new DbMigrator(new TMigrationsConfiguration());
var migrations = migrator.GetPendingMigrations().ToList();
if (migrations.Any())
{
var message = "There are pending migrations that must be applied (via a script or using migrate.exe) before the application is started.\r\n" +
$"Pending migrations:\r\n{string.Join("\r\n", migrations)}";
throw new MigrationsPendingException(message);
}
}
}运行对活动数据库的迁移
$migrate = "<path>\migrate.exe"
$migrateConfig = "<path>\migrate.exe.config"
$connectionString = <your-live-connection-string>
& $migrate <your-project-migration-assembly> /startupConfigurationFile=$migrateConfig <your-migration-configuration-type-name> /connectionString=$connectionString /connectionProviderName=System.Data.SqlClient /verbosehttps://stackoverflow.com/questions/38669620
复制相似问题