Я использую управление выпуском TFS для непрерывной интеграции и развертывания.
Я использую 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