Ich verwende das TFS-Versionsmanagement für die fortlaufende Integration und Bereitstellung.Erste Migration des EF-Codes für die Bereitstellung einer älteren Version
Ich verwende migrate.exe, um die Datenbankmigration während der Bereitstellung durchzuführen. Dies funktioniert sehr gut, wenn Sie von einer älteren Version auf eine neuere Version wechseln. Wenn Sie eine ältere Version der Anwendung bereitstellen möchten, wird es jedoch matschiger. Die Assembly, die Ihre Migrationen für einen Kontext enthält, muss wissen, wie Sie von Version 3 zu Version 2 wechseln können. Normalerweise verwenden Sie die Assemblys, die Sie als Quelle für Ihre Migrationen bereitstellen möchten, aber in diesem Fall Fall, Sie müssen die bereits bereitgestellten Assemblies verwenden, da sie die einzigen sind, die wissen, wie man von v3 auf v2 herunterkommt. (Version 2 hat keine Ahnung, dass v3 überhaupt existiert.)
Mein aktueller Plan ist es, die beiden Baugruppen während der Bereitstellung irgendwie zu vergleichen. Wenn die Montag im Installationsverzeichnis „neuer“ Migrationen als die im Deployment-Direktor enthält, würde ich zuerst die „neueste“ verfügbar Migration in der Versammlung im Bereitstellungsverzeichnis erhalten muß, und dann auszuführen:
migrate.exe AssemblyInInstallationDir /targetMigration NewestFromAssemblyInDeploymentDir
wo, wie in einem „normalen“ Einsatz-Szenario, wo Sie auf eine neuere Version aktualisieren, können Sie einfach tun:
migrate.exe AssemblyInDeploymentDir
Ist dies ein legit Ansatz? Ich habe noch zu prüfen, mit EF-Bibliotheken zu bewerten, welche Migrationen in jeder Baugruppe verfügbar sind. Es besteht auch die Herausforderung, dass jede dieser Baugruppen die "gleichen" nur unterschiedlichen Versionen sind. Ich muss sie wahrscheinlich in separate App-Domains laden und dann die Cross-App-Domain-Kommunikation nutzen, um die benötigten Informationen zu erhalten.
EDIT
habe ich ein Proof of Concept-App, die mir die verfügbaren Migrationen auf zwei verschiedene Versionen der gleichen Baugruppe auflisten können. Dies war für den gesamten Prozess von entscheidender Bedeutung, daher dachte ich, dass es sich lohnt, zu dokumentieren.
Die Anwendung verwendet Reflektion, um jede Assembly zu laden, und verwendet dann die DbMigrator-Klasse von System.Data.Entity.Migrations, um die Migrationsmetadaten aufzuzählen. Den Namen der Migrationen sind die Zeitstempelinformationen vorangestellt. Dadurch kann ich sie ordnen und sehen, welche Assembly den "neueren" Satz von Migrationen enthält.
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();
}
}
Die Ausgabe der Anwendung wie folgt aussieht:
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
Ich weiß nicht, die Antwort, ob dies eine akzeptierte Möglichkeit, dies zu tun, aber ein dickes Lob für die Dokumentation und Ihren Ansatz zu teilen. –