Freigeben über


Code First Migrations mit einer vorhandenen Datenbank

Hinweis

Nur EF4.3 und höher – Die in dieser Seite besprochenen Features, APIs usw. wurden in Entity Framework 4.1 eingeführt. Wenn Sie eine frühere Version verwenden, gelten einige oder alle Informationen nicht.

In diesem Artikel wird die Verwendung von Code First-Migrationen mit einer vorhandenen Datenbank behandelt, die nicht von Entity Framework erstellt wurde.

Hinweis

In diesem Artikel wird davon ausgegangen, dass Sie wissen, wie Sie Code First-Migrationen in grundlegenden Szenarien verwenden. Wenn Sie dies nicht tun, müssen Sie Code First Migrations lesen, bevor Sie fortfahren.

Schritt 1: Erstellen eines Modells

Der erste Schritt ist das Erstellen eines Code First-Modells, das auf Ihre vorhandene Datenbank ausgerichtet ist. Im Thema "Code First to an Existing Database " finden Sie ausführliche Anleitungen dazu.

Hinweis

Es ist wichtig, die restlichen Schritte in diesem Thema zu befolgen, bevor Sie Änderungen am Modell vornehmen, die Änderungen am Datenbankschema erfordern. Bei den folgenden Schritten muss das Modell mit dem Datenbankschema synchronisiert werden.

Schritt 2: Aktivieren von Migrationen

Der nächste Schritt besteht darin, Migrationen zu aktivieren. Sie können dies tun, indem Sie den Befehl "Migration aktivieren" in der Paket-Manager-Konsole ausführen.

Mit diesem Befehl wird ein Ordner in Ihrer Lösung namens "Migrationen" erstellt und eine einzelne Klasse darin eingefügt, die als "Configuration" bezeichnet wird. Die Konfigurationsklasse ist der Ort, an dem Sie Migrationen für Ihre Anwendung konfigurieren. Weitere Informationen hierzu finden Sie im Thema "Code First Migration" .

Schritt 3: Hinzufügen einer anfänglichen Migration

Nachdem Migrationen erstellt und auf die lokale Datenbank angewendet wurden, können Sie diese Änderungen auch auf andere Datenbanken anwenden. Ihre lokale Datenbank kann z. B. eine Testdatenbank sein, und Sie können letztendlich auch die Änderungen auf eine Produktionsdatenbank und/oder andere Entwicklertestdatenbanken anwenden. Für diesen Schritt gibt es zwei Optionen, die Sie auswählen sollten, hängt davon ab, ob das Schema anderer Datenbanken leer ist oder derzeit mit dem Schema der lokalen Datenbank übereinstimmt.

  • Option 1: Verwenden Sie vorhandenes Schema als Ausgangspunkt. Sie sollten diesen Ansatz verwenden, wenn andere Datenbanken, auf die Migrationen in Zukunft angewendet werden, dasselbe Schema wie ihre lokale Datenbank aufweist. Sie können dies beispielsweise verwenden, wenn Ihre lokale Testdatenbank derzeit v1 Ihrer Produktionsdatenbank entspricht und Sie diese Migrationen später anwenden, um Ihre Produktionsdatenbank auf v2 zu aktualisieren.
  • Option 2: Leere Datenbank als Ausgangspunkt verwenden. Sie sollten diesen Ansatz verwenden, wenn andere Datenbanken, auf die Migrationen in Zukunft angewendet werden, leer sind (oder noch nicht vorhanden sind). Sie können dies beispielsweise verwenden, wenn Sie mit der Entwicklung Ihrer Anwendung mit einer Testdatenbank begonnen haben, aber ohne Migrationen und später eine Produktionsdatenbank von Grund auf neu erstellen möchten.

Option 1: Verwenden eines vorhandenen Schemas als Ausgangspunkt

Code First Migration verwendet eine Momentaufnahme des Modells, das in der letzten Migration gespeichert ist, um Änderungen am Modell zu erkennen (Detaillierte Informationen hierzu finden Sie in Code First Migrationen in Teamumgebungen). Da davon ausgegangen wird, dass Datenbanken bereits über das Schema des aktuellen Modells verfügen, generieren wir eine leere (no-op) Migration, die das aktuelle Modell als Momentaufnahme aufweist.

  1. Führen Sie den Befehl Add-Migration InitialCreate –IgnoreChanges in der Paket-Manager-Konsole aus. Dadurch wird eine leere Migration mit dem aktuellen Modell als Momentaufnahme erstellt.
  2. Führen Sie den Befehl "Update-Datenbank" in der Paket-Manager-Konsole 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.

Option 2: Verwenden einer leeren Datenbank als Ausgangspunkt

In diesem Szenario müssen Wir Migrationen benötigen, um die gesamte Datenbank von Grund auf neu zu erstellen – einschließlich der Tabellen, die bereits in unserer lokalen Datenbank vorhanden sind. Wir erstellen eine InitialCreate-Migration, die Logik zum Erstellen des vorhandenen Schemas enthält. Dann sehen wir unsere vorhandene Datenbank so aus, als wäre diese Migration bereits angewendet worden.

  1. Führen Sie den Befehl Add-Migration InitialCreate in der Paket-Manager-Konsole aus. Dadurch wird eine Migration erstellt, um das vorhandene Schema zu erstellen.
  2. Kommentieren Sie sämtlichen 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 neu zu erstellen.
  3. Führen Sie den Befehl "Update-Datenbank" in der Paket-Manager-Konsole 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.
  4. Entfernen Sie die Kommentierung des Codes in der Up-Methode. Dies bedeutet, dass bei der Anwendung dieser Migration auf zukünftige Datenbanken das Schema, das bereits in der lokalen Datenbank vorhanden ist, durch Migrationen erstellt wird.

Zu beachtende Dinge

Es gibt ein paar Dinge, die Sie bei der Verwendung von Migrationen für eine vorhandene Datenbank beachten müssen.

Standard-/berechnete Namen stimmen möglicherweise nicht mit dem vorhandenen Schema überein.

Migrationen geben explizit Namen für Spalten und Tabellen an, wenn ein Gerüst für eine Migration erstellt wird. Es gibt jedoch andere Datenbankobjekte, für die Migrationen beim Anwenden der Migrationen einen Standardnamen berechnet. Dazu gehören Indizes und Fremdschlüsseleinschränkungen. Bei der Ausrichtung auf ein vorhandenes Schema stimmen diese berechneten Namen möglicherweise nicht mit den tatsächlich in Ihrer Datenbank vorhandenen Namen überein.

Im Folgenden finden Sie einige Beispiele dafür, wann Sie dies beachten müssen:

Wenn Sie "Option One: Vorhandenes Schema als Ausgangspunkt verwenden" aus Schritt 3 verwendet haben:

  • Wenn zukünftige Änderungen in Ihrem Modell erfordern, ein Datenbankobjekt zu ändern oder zu entfernen, das einen anderen Namen trägt, müssen Sie die generierte Migration anpassen, um den korrekten Namen anzugeben. Die Migrations-APIs verfügen über einen optionalen Name-Parameter, mit dem Sie dies ausführen können. Ihr vorhandenes Schema kann z. B. eine Post-Tabelle mit einer BlogId-Fremdschlüsselspalte aufweisen, die einen Index mit dem Namen IndexFk_BlogId hat. Standardmäßig erwarten Migrationen jedoch, dass dieser Index IX_BlogId benannt wird. Wenn Sie eine Änderung an Ihrem Modell vornehmen, das zum Ablegen dieses Indexes führt, müssen Sie den Gerüst-DropIndex-Aufruf ändern, um den IndexFk_BlogId Namen anzugeben.

Wenn Sie "Option Two: Leere Datenbank als Ausgangspunkt verwenden" aus Schritt 3 verwendet haben:

  • Beim Versuch, die Down-Methode der anfänglichen Migration (d. h. das Zurücksetzen auf eine leere Datenbank) für die lokale Datenbank auszuführen, tritt möglicherweise ein Fehler auf, da Migrationen versuchen, Indizes und Fremdschlüsseleinschränkungen mit den falschen Namen abzulegen. Dies wirkt sich nur auf Ihre lokale Datenbank aus, da andere Datenbanken mit 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, ist dies am einfachsten, indem Sie die Datenbank ablegen oder alle Tabellen ablegen. Nach diesem anfänglichen Downgrade werden alle Datenbankobjekte mit den Standardnamen neu erstellt, sodass dieses Problem nicht mehr angezeigt wird.
  • Wenn zukünftige Änderungen in Ihrem Modell eine der Datenbankobjekte ändern oder ablegen müssen, die anders benannt werden, funktioniert dies nicht für Ihre vorhandene lokale Datenbank, da die Namen nicht den Standardwerten entsprechen. Es funktioniert jedoch nicht mit Datenbanken, die von Grund auf neu erstellt wurden, da sie die Standardnamen verwendet haben, die von Migrations ausgewählt wurden. Sie können diese Änderungen entweder manuell in Ihrer lokalen vorhandenen Datenbank vornehmen oder erwägen, Migrations die Datenbank von Grund auf neu erstellen zu lassen – wie auf anderen Rechnern.
  • Datenbanken, die mit der Up-Methode Der ursprü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 haben Sie auch zusätzliche Indizes, da Migrationen standardmäßig 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 von Migrationen nicht behandelt. Dazu können Ansichten, gespeicherte Prozeduren, Berechtigungen, 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 Option, die Sie in „Schritt 3“ ausgewählt haben, wird das Migrationstool nicht automatisch erkennen, wenn zukünftige Änderungen in Ihrem Modell erforderlich sind, um diese zusätzlichen Objekte zu ändern oder zu entfernen. Wenn Sie beispielsweise eine Spalte ablegen, die über einen zusätzlichen Index verfügt, ist der Migrationsprozess nicht in der Lage, den Index automatisch abzulegen. Sie müssen dies manuell zur vorstrukturierten Migration hinzufügen.
  • Wenn Sie "Option Two: Leere Datenbank als Ausgangspunkt verwenden" verwendet haben, werden diese zusätzlichen Objekte nicht von der Up-Methode der ersten Migration erstellt. Sie können die Methoden "Up" und "Down" ändern, um diese zusätzlichen Objekte bei Bedarf zu berücksichtigen. Für Objekte, die in der Migrations-API nicht nativ unterstützt werden, wie z. B. Sichten, können Sie die SQL-Methode verwenden, um Roh-SQL auszuführen, um sie zu erstellen oder zu löschen.