Code First-Migrationen für eine vorhandene Datenbank
Hinweis
Nur EF4.3 und höher: Die auf dieser Seite erläuterten Features, APIs usw. wurden in Entity Framework 4.1 eingeführt. Wenn Sie eine frühere Version verwenden, gelten manche Informationen nicht.
In diesem Artikel wird die Verwendung von Code First-Migrationen für eine vorhandene Datenbank behandelt, die nicht von Entity Framework erstellt wurde.
Hinweis
In diesem Artikel wird davon ausgegangen, dass Ihnen bekannt ist, wie Sie Code First-Migrationen in Basisszenarien verwenden. Wenn nicht, sollten Sie Code First-Migrationen lesen, bevor Sie fortfahren.
Schritt 1: Erstellen eines Modells
Der erste Schritt besteht im Erstellen eines Code First-Modells für Ihre bestehende Datenbank. Einen ausführlichen Leitfaden zu diesem Thema finden Sie unter Code First für eine bestehende Datenbank.
Hinweis
Es ist wichtig, die restlichen Schritte dieses Thema zu befolgen, bevor Sie Änderungen am Modell vornehmen, die Änderungen am Datenbankschema erfordern würden. Bei den folgenden Schritten muss das Modell mit dem Datenbankschema synchronisiert werden.
Schritt 2: Aktivieren des Migrationstools
Der nächste Schritt besteht darin, das Migrationstool zu aktivieren. Sie können dies tun, indem Sie in der Paket-Manager-Konsole den Befehl Enable-Migrations (Migrationen aktivieren) ausführen.
Mit diesem Befehl wird ein Ordner namens „Migrations“ erstellt und eine einzelne Klasse mit dem Namen „Configuration“ darin eingefügt. Die Configuration-Klasse ist der Ort, an dem Sie Migrationen für Ihre Anwendung konfigurieren können. Weitere Informationen zu diesem Thema finden Sie unter Code First-Migrationen.
Schritt 3: Hinzufügen einer anfänglichen Migration
Nachdem Migrationen erstellt und auf die lokale Datenbank angewendet wurden, möchten Sie diese Änderungen möglicherweise auch auf andere Datenbanken anwenden. Ihre lokale Datenbank kann beispielweise eine Testdatenbank sein, und Sie möchten die Änderungen schlussendlich auf eine Produktionsdatenbank und/oder andere Testdatenbanken für die Entwicklung anwenden. Für diesen Schritt haben Sie zwei Möglichkeiten, wobei die, die Sie auswählen sollten, davon abhängt, ob das Schema anderer Datenbanken leer ist oder derzeit mit dem Schema der lokalen Datenbank übereinstimmt.
- Möglichkeit 1: Verwenden eines vorhandenen Schemas als Ausgangspunkt Sie sollten diesen Ansatz wählen, wenn andere Datenbanken, auf die Migrationen in Zukunft angewendet werden sollen, dasselbe Schema wie ihre lokale Datenbank aufweisen. Sie können so beispielsweise vorgehen, wenn Ihre lokale Testdatenbank derzeit der Version v1 Ihrer Produktionsdatenbank entspricht und Sie diese Migrationen später anwenden wollen, um Ihre Produktionsdatenbank auf die Version v2 zu aktualisieren.
- Möglichkeit 2: Verwenden einer leeren Datenbank als Ausgangspunkt Sie sollten diesen Ansatz wählen, wenn andere Datenbanken, auf die Migrationen in Zukunft angewendet werden sollen, leer (oder noch nicht vorhanden) sind. Sie können so beispielsweise vorgehen, wenn Sie bei der Entwicklung Ihrer Anwendung mit einer Testdatenbank, aber ohne Migrationen begonnen haben und später eine Produktionsdatenbank von Grund auf neu erstellen möchten.
Möglichkeit 1: Verwenden eines vorhandenen Schemas als Ausgangspunkt
Code First-Migrationen verwenden eine Momentaufnahme des Modells, das in der letzten Migration gespeichert wurde, um Änderungen am Modell zu erkennen. (Detaillierte Informationen hierzu finden Sie unter Code First-Migrationen in Teamumgebungen.) Da wir davon ausgehen, dass Datenbanken bereits über das Schema des aktuellen Modells verfügen, generieren wir eine leere (no-op)-Migration mit dem aktuellen Modell als Momentaufnahme.
- Führen Sie in der Paket-Manager-Konsole den Befehl Add-Migration InitialCreate –IgnoreChanges aus. Dadurch wird eine leere Migration mit dem aktuellen Modell als Momentaufnahme erstellt.
- Führen Sie in der Paket-Manager-Konsole den Befehl Update-Database aus. Dadurch wird die InitialCreate-Migration auf die Datenbank angewendet. Da die tatsächliche Migration keine Änderungen enthält, fügt sie einfach eine Zeile zur „__MigrationsHistory“-Tabelle hinzu, die angibt, dass diese Migration bereits angewendet wurde.
Möglichkeit 2: Verwenden einer leeren Datenbank als Ausgangspunkt
In diesem Szenario benötigen wir das Migrationstool, um die gesamte Datenbank von Grund auf neu zu erstellen. Dazu zählen auch die Tabellen, die bereits in unserer lokalen Datenbank vorhanden sind. Wir generieren eine InitialCreate-Migration, die die Logik zum Erstellen des vorhandenen Schemas enthält. Anschließend gestalten wir unsere vorhandene Datenbank so, als wäre diese Migration bereits angewendet worden.
- Führen Sie in der Paket-Manager-Konsole den Befehl Add-Migration InitialCreate aus. Dadurch wird eine Migration erstellt, um das vorhandene Schema zu erstellen.
- Kommentieren Sie den gesamten Code in der Up-Methode der neu erstellten Migration aus. Auf diese Weise können wir ‘die Migration auf die lokale Datenbank anwenden, ohne alle bereits vorhandenen Tabellen usw. neu zu erstellen.
- Führen Sie in der Paket-Manager-Konsole den Befehl Update-Database aus. Dadurch wird die InitialCreate-Migration auf die Datenbank angewendet. Da die tatsächliche Migration keine Änderungen enthält (da wir sie vorübergehend auskommentiert haben), fügt sie einfach eine Zeile zur „__MigrationsHistory“-Tabelle hinzu, die angibt, dass diese Migration bereits angewendet wurde.
- Entfernen Sie den Kommentar für den Code in der Up-Methode. Dies bedeutet, dass das Schema, das bereits in der lokalen Datenbank vorhanden ist, von Migrationen erstellt wird, wenn diese Migration auf zukünftige Datenbanken angewendet wird.
Worauf Sie achten sollten
Es gibt ein paar Dinge, die Sie bei der Verwendung des Migrationstools für eine vorhandene Datenbank beachten sollten.
Standard-/berechnete Namen stimmen möglicherweise nicht mit dem vorhandenen Schema überein
Das Migrationstool gibt explizit Namen für Spalten und Tabellen an, wenn ein Migrationsentwurf erstellt wird. Es gibt jedoch andere Datenbankobjekte, für die das Migrationstool beim Anwenden von Migrationen einen Standardname berechnet. Dazu gehören Indizes und Fremdschlüsseleinschränkungen. Bei der Verwendung eines vorhandenen Schemas stimmen diese berechneten Namen möglicherweise nicht mit den tatsächlich in Ihrer Datenbank vorhandenen überein.
Im Folgenden finden Sie einige Beispiele dafür, wann Sie dies beachten müssen:
Wenn Sie die Möglichkeit 1 aus Schritt 3 (Verwenden eines vorhandenen Schemas als Ausgangspunkt) gewählt haben:
- Wenn zukünftige Änderungen in Ihrem Modell das Ändern oder Ablegen von Datenbankobjekten erforderlich machen, die anders benannt sind, müssen Sie den Migrationsentwurf ändern und den richtigen Namen angeben. Die Migrations-APIs verfügen dafür über einen optionalen Name-Parameter. Nehmen wir beispielsweise an, ihr vorhandenes Schema wäre Post-Tabelle mit einer BlogId-Fremdschlüsselspalte, die einen Index mit dem „Namen IndexFk_BlogId“ hätte. Standardmäßig würden das Migrationstool jedoch erwarten, dass dieser Index den Namen „IX_BlogId“ hat. Wenn Sie eine Änderung an Ihrem Modell vornehmen würden, die zum Ablegen dieses Indexes führen würde, müssten Sie den DropIndex-Aufruf für den Entwurf ändern und als Namen „IndexFk_BlogId“ angeben.
Wenn Sie die Möglichkeit 2 aus Schritt 3 (Verwenden einer leeren Datenbank als Ausgangspunkt) gewählt haben:
- Beim Versuch, die Down-Methode der anfänglichen Migration für die lokale Datenbank auszuführen (d. h. sie auf eine leere Datenbank zurückzusetzen), tritt möglicherweise ein Fehler auf, da das Migrationstool beim Versuch, Indizes und Fremdschlüsseleinschränkungen abzulegen, die falschen Namen verwenden. Dies wirkt sich nur auf Ihre lokale Datenbank aus, da andere Datenbanken mithilfe der Up-Methode der anfänglichen Migration von Grund auf neu erstellt werden. Wenn Sie die vorhandene lokale Datenbank auf einen leeren Zustand herabstufen möchten, besteht der einfachste Weg darin, die Datenbank oder alle Tabellen abzulegen. Nach dieser anfänglichen Herabstufung werden alle Datenbankobjekte mit den Standardnamen neu erstellt, sodass dieses Problem nicht mehr auftritt.
- Wenn zukünftige Änderungen in Ihrem Modell das Ändern oder Ablegen eines Datenbankobjekts erfordern, das anders benannt ist, wird dies für Ihre vorhandene lokale Datenbank nicht funktionieren, da die Namen nicht den Standardwerten entsprechen. Die Vorgänge funktionieren jedoch bei Datenbanken, die von Grund auf neu erstellt wurden, da sie die Standardnamen verwenden, die vom Migrationstool ausgewählt wurden. Sie können diese Änderungen entweder manuell in Ihrer lokalen vorhandenen Datenbank vornehmen oder erwägen, die Datenbank wie auf anderen Computern mithilfe des Migrationstools von Grund auf neu zu erstellen.
- Datenbanken, die mit der Up-Methode der anfänglichen Migration erstellt wurden, können sich geringfügig von der lokalen Datenbank unterscheiden, da die berechneten Standardnamen für Indizes und Fremdschlüsseleinschränkungen verwendet werden. Möglicherweise finden Sie auch zusätzliche Indizes, da das Migrationstool Indizes für Fremdschlüsselspalten erstellen. Dies war in Ihrer ursprünglichen lokalen Datenbank möglicherweise nicht der Fall.
Nicht alle Datenbankobjekte werden im Modell dargestellt
Datenbankobjekte, die nicht Teil Ihres Modells sind, werden vom Migrationstool nicht verarbeitet. Dazu können Ansichten, gespeicherte Prozeduren, Berechtigungen und Tabellen gehören, die nicht Teil Ihres Modells, zusätzliche Indizes usw. sind.
Im Folgenden finden Sie einige Beispiele dafür, wann Sie dies beachten müssen:
- Unabhängig von der Möglichkeit, die Sie unter „Schritt 3“ gewählt haben, kann das Migrationstool nicht wissen, ob zukünftige Änderungen in Ihrem Modell das Ändern oder Ablegen dieser zusätzlichen Objekte erforderlich machen. Wenn Sie beispielsweise eine Spalte ablegen, die über einen zusätzlichen Index verfügt, weiß das Migrationstool nicht, dass es auch den Index ablegen soll. Sie müssen dies manuell zum Migrationsentwurf hinzufügen.
- Wenn Sie sich für „Möglichkeit 2“ (Verwenden einer leeren Datenbank als Ausgangspunkt) entschieden haben, werden diese zusätzlichen Objekte nicht von der Up-Methode der anfänglichen Migration erstellt. Sie können die Up- und Down-Methoden ändern, um diese zusätzlichen Objekte auf Wunsch zu berücksichtigen. Für Objekte wie Ansichten, die in der Migrations-API nicht nativ unterstützt werden, können Sie die SQL-Methode verwenden, um sie mithilfe von unformatiertem SQL zu erstellen bzw. abzulegen.