Schema Migration
Die neue Schema Migration wurde von Grund auf neu geschrieben. Der Fokus lag dabei auf Verständlichkeit, Wartbarkeit, Sauberkeit, Erweiterbarkeit und natürlich Verlässlichkeit. Um diese Ziele zu erreichen, wurde die Migration in möglichst wenige Einzelteile aufgeteilt, damit immer klar ist, welche Methode in welcher Klasse welche Auswirkungen hat.
Breaking Changes
DBMS Objekte tragen jetzt 1:1 den Namen wie im Model und werden nicht mehr gelowered
Ausgenommen sind hier die Tabellennamen, die weiterhin den Modellnamen als Prefix tragen
Es ist nicht mehr möglich von uns gemanagte Trigger zu erweitern
Falls dies gewünscht ist kann die Migrationsmethode für Trigger manuell überschrieben werden; mehr dazu unter Erweiterbarkeit
Die Definition von PrimaryKey-Indexen hat sich verändert:
Integer-basierte PrimaryKey-Indexe werden als Clustered Index erstellt (wie bis anhin)
GUID-basierte PrimaryKey-Indexe werden als NonClustered Index erstellt
Grundlagen
Für die Benutzer der Migration, die keine Änderungen am Standardverhalten vorgenommen haben, hat sich nichts verändert. Die neue Version ist ein Drop-In Replacement und ist in Releases ab Quino Standard Version 10.23.0116.1 enthalten.
Beim ersten Start einer Applikation mit der neuen Migration wird die bestehende Datenbank automatisch angepasst. Dabei werden alle von uns gemanagten DBMS-Objekte so umbenannt, dass sie den gleichen Namen, wie im Model tragen. Manuell erstelle Scripte, Trigger, Views, etc. müssen also an diese neuen Namen angepasst werden.
Aufbau
Die neue Migration ist grob in zwei Teile aufgeteilt.
Schema Creator
Der Schema Creator stellt nur eine Methode zur Verfügung.
DatabaseSchema CreateSchemaForModel(IMetaModel model, ILogger logger, string connectionString)
wandelt das Bloqs-Modell in einDatabaseSchema
um, stellt sicher, dass das Modell valid ist und gibt die Möglichkeit feinere Anpassungen am Schema zu machen. Als Rückgabewert erhält man hier einDatabaseSchema
.
Der ConnectionString ist optional.
Um Datenbankspezifisches Verhalten zu erzielen gibt es zudem für jedes DBMS eine Ableitung; siehe PostgreSqlSchemaCreator.cs
, SqlServerSchemaCreator.cs
. Unterscheiden können sich z.B. Precision
und Scale
von Zahlenformaten, das Verhalten Triggern
oder auch die Erstellung der Indexe.
Das MSSQL Cascading-Verhalten ist weiterhin suboptimal und wird dementsprechend manuell via Triggern gehandhabt. Dies trifft auf andere DBMS nicht zu.
Schema Migrator
Der Schema Migrator stellt mehrere Methoden zur Verfügung.
IList<Difference> CompareModelWithDatabase(IMetaModel model, ILogger logger)
nimmt einIMetaModel
entgegen, vergleicht dieses mit der bestehenden Datenbank und gibt eine Liste anDifference
s zurück. Diese Methode kann zum Beispiel dazu verwendet werden, das bestehende Model mit den tatsächlichen Daten in der Datenbank zu vergleichen und macht es so sehr einfach die beiden abzugleiche; interessant unter anderem für DB-First Szenarien.MigrationPlan GenerateMigrationPlan(IMetaModel model, ILogger logger)
nimmt einIMetaModel
entgegen, vergleicht dieses mit der bestehenden Datenbank und generiert dann einenMigrationPlan
. Dieser Plan enthält alle Informationen notwendig, um die bestehende Datenbank an das gegebeneIMetaModel
anzupassen.bool TryMigrateDatabase(MigrationPlan migrationPlan, ILogger logger)
nimmt denMigrationPlan
entgegen und wendet diesen dann auf die konfigurierte Datenbank an. Dieser Prozess ist komplett von den restlichen Bloqs ADO-Funktionen losgelöst.
Um Datenbankspezifisches Verhalten zu erzielen gibt es zudem für jedes DBMS eine Ableitung; siehe PostgreSqlSchemaMigrator.cs
, SqlServerSchemaMigrator.cs
. Unterscheiden kann sich z.B. wie Daten in der Datenbank gespeichert werden, was unter Umständen eine Umwandlung notwendig macht. Zudem werden diese Ableitungen dazu verwendet die Verbindung mit der korrekte Datenbank aufzubauen und die Datenbankabhängigen Abhängigkeiten zu injizieren.
Erweiterbarkeit
In manchen Fällen ist es gewünscht oder Notwendig die Migration anzupassen. Um dies zu ermöglichen wurde die komplette Migration möglichst offen gestaltet. Jede interne Methode ist als protected virtual
markiert und kann einfach überschrieben werden. So ist es z.B. möglich einzelne Aspekte der Migration zu verändern, ohne den Rest anfassen zu müssen. Zudem sind Methoden, die neue Objekte generieren, immer auch einzeln überschreibbar, um möglichst modular zu sein.
Konfiguration
Durch die Applikationskonfiguration (standard IConfiguration) besteht die Möglichkeit die Migration zu konfigurieren. Um dies zu tun muss einfach nur ein neuer Key mit dem Namen SchemaMigration
angelegt werden. Aktuell steht aber nur eine Option zur Verfügung.
RunInTransaction
: Konfiguriert, ob die Migration in einer DB-Transaktion ausgeführt werden soll; default: true
.