Verwalten von Migrationen
Wenn sich Ihr Modell ändert, werden Migrationen als Teil der normalen Entwicklung hinzugefügt und entfernt, und die Migrationsdateien werden in die Quellcodeverwaltung Ihres Projekts eingecheckt. Zum Verwalten von Migrationen müssen Sie zuerst die EF Core-Befehlszeilentoolsinstallieren.
Tipp
Wenn sich DbContext
in einer anderen Assembly als das Startprojekt befindet, können Sie die Ziel- und Startprojekte explizit in den Tools für die Paket-Manager-Konsole oder die .NET Core-CLI angeben.
Hinzufügen einer Migration
Nachdem Ihr Modell geändert wurde, können Sie eine Migration für diese Änderung hinzufügen:
dotnet ef migrations add AddBlogCreatedTimestamp
Der Migrationsname kann wie eine Commitnachricht in einem Versionskontrollsystem verwendet werden. Sie können beispielsweise einen Namen wie AddBlogCreatedTimestamp wählen, wenn es sich bei der Änderung um eine neue CreatedTimestamp
-Eigenschaft für Ihre Blog
-Entität handelt.
Drei Dateien werden Ihrem Projekt im Verzeichnis Migrationen hinzugefügt:
- XXXXXXXXXXXXXX_AddCreatedTimestamp.cs – Die Hauptdatei der Migration. Enthält die Vorgänge, die zum Durchführen der Migration (in
Up
) und Rückgängigmachen (inDown
) erforderlich sind. - XXXXXXXXXXXXXX_AddCreatedTimestamp.Designer.cs – Die Metadatendatei der Migration. Enthält Informationen, die vom EF verwendet werden.
- MyContextModelSnapshot.cs – Eine Momentaufnahme des aktuellen Modells. Diese wird verwendet, um festzustellen, was sich beim Hinzufügen der nächsten Migration geändert hat.
Mit dem Zeitstempel im Dateinamen können Migrationen chronologisch angeordnet werden, sodass Sie den Fortschritt der Änderungen mitverfolgen können.
Namespaces
Es steht Ihnen frei, Migrationsdateien zu verschieben und ihren Namespace manuell zu ändern. Neue Migrationen werden als gleichgeordnete Elemente der letzten Migration erstellt. Alternativ können Sie das Verzeichnis zur Generierungszeit wie folgt angeben:
dotnet ef migrations add InitialCreate --output-dir Your/Directory
Hinweis
Sie können den Namespace auch unabhängig vom Verzeichnis mithilfe von --namespace
ändern.
Anpassen des Migrationscodes
Obwohl EF Core in der Regel genaue Migrationen erstellt, sollten Sie den Code immer überprüfen und sicherstellen, dass er der gewünschten Änderung entspricht. In einigen Fällen ist dies sogar notwendig.
Spaltenumbenennungen
Ein bemerkenswertes Beispiel, bei dem das Anpassen von Migrationen erforderlich ist, ist die Umbenennung einer Eigenschaft. Wenn Sie beispielsweise eine Eigenschaft von Name
in FullName
umbenennen, wird EF Core die folgende Migration generieren:
migrationBuilder.DropColumn(
name: "Name",
table: "Customers");
migrationBuilder.AddColumn<string>(
name: "FullName",
table: "Customers",
nullable: true);
EF Core kann in der Regel nicht wissen, wann die Absicht besteht, eine Spalte abzulegen und eine neue zu erstellen (zwei separate Änderungen), und wann eine Spalte umbenannt werden soll. Wenn die obige Migration unverändert angewendet wird, gehen alle Ihre Kundennamen verloren. Um eine Spalte umzubenennen, ersetzen Sie die oben generierte Migration durch Folgendes:
migrationBuilder.RenameColumn(
name: "Name",
table: "Customers",
newName: "FullName");
Tipp
Der Einrüstvorgang der Migration warnt, wenn bei einem Vorgang Datenverlust eintreten kann (etwa beim Verwerfen einer Spalte). Wenn diese Warnung angezeigt wird, überprüfen Sie den Migrationscode besonders gründlich auf Genauigkeit.
Hinzufügen von unformatiertem SQL
Obwohl das Umbenennen einer Spalte über eine integrierte API erreicht werden kann, ist dies in vielen Fällen nicht möglich. Beispielsweise möchten wir vorhandene FirstName
- und LastName
-Eigenschaften durch eine einzelne, neue FullName
-Eigenschaft ersetzen. Die von EF Core generierte Migration wird wie folgt aussehen:
migrationBuilder.DropColumn(
name: "FirstName",
table: "Customer");
migrationBuilder.DropColumn(
name: "LastName",
table: "Customer");
migrationBuilder.AddColumn<string>(
name: "FullName",
table: "Customer",
nullable: true);
Wie zuvor würde dies zu unerwünschtem Datenverlust führen. Um die Daten aus den alten Spalten zu übertragen, ordnen wir die Migrationen neu an und führen einen unformatierten SQL-Vorgang wie folgt ein:
migrationBuilder.AddColumn<string>(
name: "FullName",
table: "Customer",
nullable: true);
migrationBuilder.Sql(
@"
UPDATE Customer
SET FullName = FirstName + ' ' + LastName;
");
migrationBuilder.DropColumn(
name: "FirstName",
table: "Customer");
migrationBuilder.DropColumn(
name: "LastName",
table: "Customer");
Willkürliche Änderungen über unformatierte SQL
Unformatierte SQL kann auch zum Verwalten von Datenbankobjekten verwendet werden, die EF Core nicht kennt. Fügen Sie dazu eine Migration hinzu, ohne eine Modelländerung vorzunehmen. Es wird eine leere Migration generiert werden, die Sie dann mit unformatierten SQL-Vorgängen auffüllen können.
Die folgende Migration erstellt beispielsweise eine gespeicherte SQL Server-Prozedur:
migrationBuilder.Sql(
@"
EXEC ('CREATE PROCEDURE getFullName
@LastName nvarchar(50),
@FirstName nvarchar(50)
AS
RETURN @LastName + @FirstName;')");
Tipp
EXEC
wird verwendet, wenn eine Anweisung die erste oder einzige in einem SQL-Batch sein muss. Es kann auch verwendet werden, um Parserfehler in idempotenten Migrationsskripts zu umgehen, die auftreten können, wenn referenzierte Spalten in einer Tabelle derzeit nicht vorhanden sind.
Dies kann verwendet werden, um jeden Aspekt Ihrer Datenbank zu verwalten, einschließlich:
- Gespeicherten Prozeduren
- Volltextsuche
- Funktionen
- Auslöser
- Ansichten
In den meisten Fällen umschließt EF Core bei der Anwendung von Migrationen automatisch jede Migration in ihre eigene Transaktion. Leider können einige Migrationsvorgänge in einigen Datenbanken nicht innerhalb einer Transaktion ausgeführt werden. In diesen Fällen können Sie die Transaktion verlassen, indem Sie suppressTransaction: true
an migrationBuilder.Sql
übergeben.
Entfernen einer Migration
Es kann vorkommen, dass Sie eine Migration hinzufügen und feststellen, dass Sie zusätzliche Änderungen an Ihrem EF Core-Modell vornehmen müssen, bevor Sie diese durchführen. Um die letzte Migration zu entfernen, verwenden Sie diesen Befehl.
dotnet ef migrations remove
Nachdem Sie die Migration entfernt haben, können Sie die zusätzlichen Modelländerungen vornehmen und sie erneut hinzufügen.
Warnung
Vermeiden Sie das Entfernen von Migrationen, die bereits auf Produktionsdatenbanken angewendet wurden. Dies würde bedeuten, dass Sie diese Migrationen nicht aus den Datenbanken wiederherstellen können und dass die Annahmen, die von nachfolgenden Migrationen gemacht werden, möglicherweise nicht mehr stimmen.
Auflisten von Migrationen
Sie können alle vorhandenen Migrationen wie folgt auflisten:
dotnet ef migrations list
Überprüfen auf ausstehende Modelländerungen
Hinweis
Dieses Feature wurde in EF Core 8.0 hinzugefügt.
Manchmal sollten Sie überprüfen, ob seit der letzten Migration Modelländerungen vorgenommen wurden. Dadurch können Sie feststellen, ob Sie oder ein Teammitglied vergessen haben, eine Migration hinzuzufügen. Eine Möglichkeit, dies zu erledigen, ist die Verwendung dieses Befehls.
dotnet ef migrations has-pending-model-changes
Sie können diese Überprüfung auch programmgesteuert mit context.Database.HasPendingModelChanges()
ausführen. Diese Methode kann verwendet werden, um einen Komponententest zu schreiben, der fehlschlägt, wenn Sie vergessen, eine Migration hinzuzufügen.
Zurücksetzen aller Migrationen
In einigen extremen Fällen kann es notwendig sein, alle Migrationen zu entfernen und von vorn zu beginnen. Dies kann ganz einfach gemacht werden, indem Sie den Ordner Migrationen löschen und Ihre Datenbank trennen. An diesem Punkt können Sie eine neue Erstmigration erstellen, die Ihr gesamtes aktuelles Schema enthalten wird.
Es ist auch möglich, alle Migrationen zurückzusetzen und eine einzelne zu erstellen, ohne Ihre Daten zu verlieren. Dies wird manchmal als „Squashing“ bezeichnet und erfordert einige manuelle Arbeit:
- Sichern Sie Ihre Datenbank, falls ein Fehler auftritt.
- Löschen Sie in Ihrer Datenbank alle Zeilen aus der Migrationsverlaufstabelle (z. B.
DELETE FROM [__EFMigrationsHistory]
in SQL Server). - Löschen Sie Ihren Ordner Migrationen.
- Erstellen Sie eine neue Migration, und generieren Sie ein SQL-Skript für diese (
dotnet ef migrations script
). - Fügen Sie eine einzelne Zeile in den Migrationsverlauf ein, um aufzuzeichnen, dass die erste Migration bereits angewendet wurde, da Ihre Tabellen bereits vorhanden sind. Das Einfügen von SQL ist der letzte Vorgang im oben generierten SQL-Skript und funktioniert folgendermaßen (vergessen Sie nicht, die Werte zu aktualisieren):
INSERT INTO [__EFMigrationsHistory] ([MIGRATIONID], [PRODUCTVERSION])
VALUES (N'<full_migration_timestamp_and_name>', N'<EF_version>');
Warnung
Der gesamte benutzerdefinierte Migrationscode wird verloren gehen, wenn der Ordner Migrationen gelöscht wird. Alle Anpassungen müssen manuell auf die neue Erstmigration angewendet werden, damit sie erhalten bleiben.
Zusätzliche Ressourcen
- Referenz zu Entity Framework Core-Tools – .NET Core CLI: Enthält Befehle zum Aktualisieren, Verwerfen, Hinzufügen, Entfernen und vielen weiteren Vorgängen.
- Referenz zu Entity Framework Core-Tools – Paket-Manager-Konsole in Visual Studio: Enthält Befehle zum Aktualisieren, Verwerfen, Hinzufügen, Entfernen und vielen weiteren Vorgängen.