.Net核心-实体框架核心迁移-生产

时间:2019-01-18 17:43:16

标签: c# asp.net-core entity-framework-core ef-migrations

在阅读了许多问题之后,在Asp.Net的Github(this one comes to mind,ServerFault和SoftwareEngineering上,我决定问一个我自己的问题。

问题

代码优先迁移使早期开发过程变得非常容易。暂存或生产环境更难更新,尤其是在可能需要频繁更新的初始部署期间。 更新生产数据库要困难得多,并且出于许多很好的原因,自动迁移是不可能的-在文档中都很好地编写和解释了这些原因,而使我忽略了这种方法。 现在我正在寻找中间立场。

方法

一旦发布了该应用程序的新版本,我们就可以检测是否有未决的更改(诊断中间件“ DatabaseErrorPageMiddleware”在使用时已经做到了这一点,显然在生产环境中不会这样做)。如果有未完成的迁移,我们可以使站点脱机(为简便起见,有多种方法可以跳过),但仍允许管理用户登录系统-可能具有特定声明“ IsAllowedToMigrate”:“ true”。 对于该用户,我们可以在他的管理导航中添加一个操作。该页面可以列出未决的更改,并公开要更新为最新的方法(为简单起见)。这种操作方法甚至可以结合代码来备份数据库或进行类似的制衡。

关于环境的假设

对于我打算使用的方法,我假设使用一种相当非正式的方法来更新应用程序-不涉及可能需要脚本的外部DBA,迁移已经在生产数据库的最新备份中进行了测试等。 其次,我假设该站点可以显示为脱机;让我们打电话给ImaginarySiteManager.DisplayOffline(AVeryNiceMessage)。该假想站点仍可以提供登录到管理后端的信息。 我也在针对SQL Server量身定制此工具,并且对其他提供程序仍然一无所知。

某些代码

大多数代码都是从中间件的来源中偷偷偷来的,要对其进行测试,我只是使用了管理员可用的ActionMethod,尚没有任何输出或动作被附加

public async Task<IActionResult> TestPendingMigrations([FromServices] SomeDbContext dbContext)
{
    var relationalDatabaseCreator = dbContext.GetService<IDatabaseCreator>() as IRelationalDatabaseCreator;
    var migrationsAssembly = dbContext.GetService<IMigrationsAssembly>();
    var modelDiffer = dbContext.GetService<IMigrationsModelDiffer>();
    var databaseExists = await relationalDatabaseCreator.ExistsAsync();

    // HasDifferences will return true if there is no model snapshot, but if there is an existing database
    // and no model snapshot then we don't want to show the error page since they are most likely targeting
    // and existing database and have just misconfigured their model

    var pendingModelChanges
        = (!databaseExists || migrationsAssembly.ModelSnapshot != null)
          && modelDiffer.HasDifferences(migrationsAssembly.ModelSnapshot?.Model, dbContext.Model);

    var pendingMigrations
        = (databaseExists
            ? await dbContext.Database.GetPendingMigrationsAsync()
            : dbContext.Database.GetMigrations())
        .ToArray();
    // get Sitemanager.CurrentSite -> isClosed; closedMessage = "updates pending.." or similar.
    // add action to admin menu (update database).


    return new EmptyResult();
}

卡在这里

首先,测试是否存在挂起的迁移应该位于启动中或启动附近。我正在尝试找出进行此设置的最佳位置。 DbContext.OnModelCreating似乎是一个不错的起点? 但是,我要如何等待它完成并插入我的SherlockHolmes模块进行调查?

在Moses的第六本书中也编写了应用迁移的代码: https://github.com/aspnet/AspNetCore/blob/master/src/Middleware/Diagnostics.EntityFrameworkCore/src/Views/DatabaseErrorPage.cshtml

因此,从理论上讲,应该有可能

  1. 启动(已更新或未更新)应用程序
  2. 启动(或派生)确定数据库是否与模型(pendingMigrations)相匹配并使网站脱机
  3. 具有特定权限(声明或其他权限)的管理员可以登录,并直接从后端运行迁移-作为唯一的授权人员(如果必须这样做)

这是可行的方法吗?我错过了Microsoft.EntityFramework.Extensions.ProductionMigrationMadeSimple扩展名吗?

0 个答案:

没有答案
相关问题