Прочитав много вопросов здесь, на Github от Asp.Net ( этот вопрос приходит на ум , ServerFault и SoftwareEngineering, я решил задать свой вопрос.
Проблема
Code-First Миграции делают жизнь невероятно легкой во время ранней разработки. Промежуточные или производственные среды сложнее обновлять, особенно во время первоначальных развертываний, которые могут потребовать частых обновлений.
Обновление рабочей БД намного сложнее, и об автоматических миграциях не может быть и речи по ряду очень веских причин - все они хорошо написаны и объяснены в документации и заставили меня игнорировать этот маршрут.
Сейчас я ищу золотую середину.
подход
После публикации новой версии приложения мы можем обнаружить наличие ожидающих изменений (связующее ПО для диагностики «DatabaseErrorPageMiddleware» делает это уже тогда, когда мы его используем, чего, очевидно, мы бы не сделали в производственной среде). Если есть ожидающие миграции, мы можем перевести сайт в автономный режим (есть разные методы, пропущенные для краткости), но все же разрешить административному пользователю войти в систему - возможно, с определенным утверждением «IsAllowedToMigrate»: «true».
Для этого пользователя мы могли бы добавить действие к его административной навигации. Эта страница может перечислить ожидающие изменения и предоставить методы для обновления до текущих (для простоты). Этот метод действия может даже включать код для резервного копирования базы данных или аналогичные проверки и противовесы.
Предположения об окружающей среде
Для моего предполагаемого подхода я предполагаю довольно неформальный подход к обновлению приложения - не задействованы внешние администраторы баз данных, которым могут потребоваться сценарии, миграции уже были протестированы на самой последней резервной копии рабочей базы данных и т. Д.
Во-вторых, я предполагаю, что Сайт может отображаться как офлайн; давайте позвоним на 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 для расследования?
Код для применения миграции также написан в шестой книге Моисея:
https://github.com/aspnet/AspNetCore/blob/master/src/Middleware/Diagnostics.EntityFrameworkCore/src/Views/DatabaseErrorPage.cshtml
Итак, теоретически должно быть возможно
- Запустить (обновлено или нет) приложение
- Запуск (или производные) выяснить, соответствует ли база данных модели (
pendingMigrations
), и перевести сайт в автономный режим
- администратор с определенным разрешением (заявкой или иным образом) может войти в систему и запустить миграцию прямо из бэкэнда - как единственное уполномоченное лицо, чтобы сделать это, если это произойдет
Это жизнеспособный подход? Я пропустил расширение Microsoft.EntityFramework.Extensions.ProductionMigrationMadeSimple
и задумался над этим?