Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
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-Befehlszeilentools installieren.
Tip
Wenn sich die DbContext Datei in einer anderen Assembly befindet als das Startprojekt, können Sie die Ziel- und Startprojekte explizit in den Paket-Manager-Konsolentools oder den .NET CLI-Tools 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 Versionssteuerungssystem verwendet werden. Sie können beispielsweise einen Namen wie "AddBlogCreatedTimestamp " auswählen, wenn die Änderung eine neue CreatedTimestamp Eigenschaft für Ihre Blog Entität ist.
Drei Dateien werden zu Ihrem Projekt im Migrations-Verzeichnis hinzugefügt.
-
XXXXXXXXXXXXXX_AddBlogCreatedTimestamp.cs- Die Hauptmigrationsdatei. Enthält die vorgänge, die zum Anwenden der Migration (in
Up) und zum Wiederherstellen der Migration (inDown) erforderlich sind. - XXXXXXXXXXXXXX_AddBlogCreatedTimestamp.Designer.cs- Die Migrationsmetadatendatei. Enthält Informationen, die von EF verwendet werden.
- MyContextModelSnapshot.cs – Eine Momentaufnahme Ihres aktuellen Modells. Wird verwendet, um zu bestimmen, was beim Hinzufügen der nächsten Migration geändert wurde.
Der Zeitstempel im Dateinamen hilft ihnen, sie chronologisch sortiert zu halten, damit Sie den Fortschritt der Änderungen sehen können.
Namespaces
Sie können Migrationsdateien verschieben und deren Namespace manuell ändern. Neue Migrationen werden als gleichgeordnete Elemente der letzten Migration erstellt. Alternativ können Sie das Verzeichnis zum Zeitpunkt der Generierung wie folgt angeben:
dotnet ef migrations add InitialCreate --output-dir Your/Directory
Note
Sie können den Namespace auch unabhängig vom Verzeichnis mithilfe von --namespace ändern.
Erstellen und Anwenden einer Migration in einem Schritt
Note
Dieses Feature wurde in EF Core 11 hinzugefügt.
Der dotnet ef database update Befehl unterstützt das Erstellen und Anwenden einer Migration in einem einzigen Schritt mithilfe der --add Option. Dabei wird Roslyn verwendet, um die Migration zur Laufzeit zu kompilieren, wodurch Szenarien wie .NET Aspire und containerisierte Anwendungen ermöglicht werden, bei denen die Anwendung nicht beendet und neu kompiliert werden kann:
dotnet ef database update InitialCreate --add
Die gleichen Optionen, die für dotnet ef migrations add verfügbar sind, können verwendet werden:
dotnet ef database update AddProducts --add --output-dir Migrations/Products --namespace MyApp.Migrations
Mit diesem Befehl wird eine neue Migration mit dem angegebenen Namen erstellt, mithilfe von Roslyn kompiliert und sofort auf die Datenbank angewendet. Die Migrationsdateien werden weiterhin auf dem Datenträger für die Quellcodeverwaltung und zukünftige Neukompilierung gespeichert.
Wenn keine ausstehenden Modelländerungen erkannt werden, wendet der Befehl vorhandene ausstehende Migrationen an, ohne eine neue zu erstellen.
Anpassen des Migrationscodes
Während EF Core im Allgemeinen genaue Migrationen erstellt, sollten Sie den Code immer überprüfen und sicherstellen, dass er der gewünschten Änderung entspricht. in einigen Fällen ist es sogar notwendig, dies zu tun.
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, generiert EF Core die folgende Migration:
migrationBuilder.DropColumn(
name: "Name",
table: "Customers");
migrationBuilder.AddColumn<string>(
name: "FullName",
table: "Customers",
nullable: true);
EF Core kann im Allgemeinen 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 oben genannte Migration as-isangewendet 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");
Tip
Der Einrüstvorgang der Migration warnt, wenn bei einem Vorgang Datenverlust eintreten kann (etwa beim Verwerfen einer Spalte). Wenn diese Warnung angezeigt wird, achten Sie insbesondere darauf, den Migrationscode auf Genauigkeit zu überprüfen.
Datenvorgänge
Migrationen können Daten verschieben und das Schema ändern. Wählen Sie den Vorgang basierend darauf aus, ob die Werte bekannt sind, wenn die Migration geschrieben wird:
- Verwenden Sie
InsertData,UpdateData, undDeleteDatafür feste Werte und Zeilen, die durch explizite Schlüssel identifiziert werden. EF Core übersetzt diese Vorgänge in anbieterspezifische SQL, sodass sie auch beim Generieren von Skripts und Bundles funktionieren. - Wird verwendet
Sql, wenn die neuen Werte aus vorhandenen Datenbankdaten berechnet werden müssen. SQL-Syntax kann je nach Anbieter unterschiedlich sein; bei Bedarf verzweigenMigrationBuilder.ActiveProvider. - Definieren Sie einen benutzerdefinierten Migrationsvorgang , wenn ein wiederverwendbarer Vorgang eine anbieterspezifische SQL-Generierung benötigt.
Verwenden Sie nicht die aktuellen DbContext ODER Entitäts-CLR-Typen, um Daten in einer Migration zu verschieben. Historische Migrationen müssen weiterhin kompiliert und sich verhalten, nachdem diese Typen geändert oder entfernt wurden.
Transformieren vorhandener Daten
Bewahren Sie beim Ersetzen von Spalten die Quelldaten auf, bis das Ziel aufgefüllt wurde:
- Fügen Sie die Zielspalte als Nullwerte hinzu.
- Füllen Sie sie aus den vorhandenen Spalten auf.
- Legen Sie bei Bedarf die Zielspalte fest.
- Legen Sie die Quellspalten ab.
Die folgende Migration implementiert diese Sequenz für SQL Server und SQLite:
migrationBuilder.AddColumn<string>(
name: "FullName",
table: "Customers",
nullable: true);
if (migrationBuilder.ActiveProvider == "Microsoft.EntityFrameworkCore.SqlServer")
{
migrationBuilder.Sql(
"""
UPDATE [Customers]
SET [FullName] = [FirstName] + N' ' + [LastName];
""");
}
else if (migrationBuilder.ActiveProvider == "Microsoft.EntityFrameworkCore.Sqlite")
{
migrationBuilder.Sql(
"""
UPDATE "Customers"
SET "FullName" = "FirstName" || ' ' || "LastName";
""");
}
else
{
throw new NotSupportedException(
$"Data migration is not implemented for provider {migrationBuilder.ActiveProvider}.");
}
migrationBuilder.AlterColumn<string>(
name: "FullName",
table: "Customers",
nullable: false,
oldClrType: typeof(string),
oldNullable: true);
migrationBuilder.DropColumn(
name: "FirstName",
table: "Customers");
migrationBuilder.DropColumn(
name: "LastName",
table: "Customers");
Fügen Sie für jeden Anbieter, den die Anwendung unterstützt, eine Verzweigung hinzu. Das Auslösen für einen unbekannten Anbieter ist sicherer als die automatische Anwendung einer unvollständigen Migration. Erstellen Sie SQL nicht aus nicht vertrauenswürdigen Werten; Die Sql-Migration wird mit Schemaänderungsberechtigungen ausgeführt.
Einige Transformationen können nicht rückgängig gemacht werden, ohne Informationen zu verlieren. Implementieren Sie Down nur, wenn die ursprünglichen Werte sicher rekonstruiert werden können. Andernfalls schlagen Sie explizit fehl und erfordern das Wiederherstellen der Daten aus einer Sicherung als Teil der Rollbackprozedur.
Einfügen von festen Daten
Wird verwendet InsertData , wenn die Schlüssel und Werte bekannt sind, wenn die Migration geschrieben wird:
migrationBuilder.InsertData(
table: "Countries",
columns: new[] { "CountryId", "Name" },
values: new object[,]
{
{ 1, "United States" },
{ 2, "Canada" }
});
Die entsprechende Down Methode sollte mit denselben Schlüsseln aufgerufen werden DeleteData .
Aktualisieren von festen Daten
UpdateData identifiziert eine Zeile anhand des Schlüssels und legt eine oder mehrere Spalten auf feste Werte fest:
migrationBuilder.UpdateData(
table: "Countries",
keyColumn: "CountryId",
keyValue: 1,
column: "Name",
value: "United States of America");
Die Down Methode sollte die vorherigen Werte wiederherstellen.
Löschen von festen Daten
DeleteData identifiziert auch Zeilen nach Schlüssel:
migrationBuilder.DeleteData(
table: "Countries",
keyColumn: "CountryId",
keyValue: 2);
Wenn die Löschung umkehrbar sein muss, sollte die Down Methode zum Wiederherstellen jedes gelöschten Werts verwendet InsertData werden. Diese Vorgänge fragen nicht den aktuellen Datenbankstatus ab; Verwenden Sql oder Initialisierungszeit-Seeding, wenn das Verhalten von vorhandenen Daten abhängt.
Willkürliche Änderungen über Roh-SQL
Raw 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; Eine leere Migration wird generiert, 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
SELECT @LastName + @FirstName;')");
Tip
EXEC wird verwendet, wenn eine Anweisung der erste oder nur eine 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 derzeit nicht in einer Tabelle vorhanden sind.
Dies kann verwendet werden, um jeden Aspekt Ihrer Datenbank zu verwalten, einschließlich:
- Gespeicherte Prozeduren
- Volltextsuche
- Functions
- Triggers
- Views
In den meisten Fällen umschließt EF Core bei der Anwendung von Migrationen automatisch jede Migration in eine eigene Transaktion. Leider können einige Migrationsvorgänge nicht innerhalb einer Transaktion in einigen Datenbanken ausgeführt werden; in diesen Fällen können Sie die Transaktion deaktivieren, indem Sie sie suppressTransaction: trueübergebenmigrationBuilder.Sql.
Note
In EF Core 9 umfasst EF Core alle ausstehenden Migrationen mit einer einzelnen Transaktion standardmäßig (dies wurde in EF Core 10 wiederhergestellt). Weitere Informationen finden Sie in der Notiz zu änderungen .
Entfernen einer Migration
Manchmal fügen Sie eine Migration hinzu und stellen fest, dass Sie zusätzliche Änderungen an Ihrem EF Core-Modell vornehmen müssen, bevor Sie sie anwenden. Verwenden Sie diesen Befehl, um die letzte Migration zu entfernen.
dotnet ef migrations remove
Nachdem Sie die Migration entfernt haben, können Sie die zusätzlichen Modelländerungen vornehmen und sie erneut hinzufügen.
Warning
Vermeiden Sie das Entfernen von Migrationen, die bereits auf Produktionsdatenbanken angewendet wurden. Dies bedeutet, dass Sie diese Migrationen in den Datenbanken nicht rückgängig machen können und möglicherweise die durch nachfolgende Migrationen getroffenen Annahmen unterbrechen.
Wenn die Migration lokal angewendet wurde
Aktualisieren Sie bei einer einwegbaren Entwicklungsdatenbank zuerst die Datenbank auf die vorherige Migration, und entfernen Sie dann die Migration aus dem Projekt. Wird beim Entfernen der ersten Migration als Ziel verwendet 0 .
dotnet ef database update PreviousMigration
dotnet ef migrations remove
--force Alternativ können Sie beide Schritte ausführen:
dotnet ef migrations remove --force
Wenn die Migration auf eine freigegebene Datenbank angewendet wurde
Löschen Sie keine Migration, die auf eine freigegebene, Test- oder Produktionsdatenbank angewendet wurde. Behalten Sie in der Regel die Migration im Projekt bei, und fügen Sie eine neue Korrekturmigration hinzu. Wenn ein geplantes Rollback erforderlich ist, führen Sie das Rollback aus, während der ursprüngliche Migrationscode noch verfügbar ist, und koordinieren Sie die Anwendungs- und Datenbankbereitstellung.
Entfernen einer älteren nicht angewendeten Migration
Die Tools entfernen nur die neueste Migration. Löschen Sie keine Migration aus der Mitte der Sequenz, und bearbeiten Sie die Modellmomentaufnahme manuell. Wenn die Migration und jede Migration nach der Veröffentlichung aufgehoben und nicht angewendet wurden, entfernen Sie die späteren Migrationen in umgekehrter Reihenfolge, entfernen Sie die unerwünschte Migration, und erstellen Sie dann das Gerüst für die beibehaltenen Modelländerungen erneut.
Wenn die Migrationen in verschiedenen Verzweigungen erstellt wurden, folgen Sie stattdessen dem unterschiedlichen Migrationsstrukturworkflow .
Auflisten von Migrationen
Sie können alle vorhandenen Migrationen wie folgt auflisten:
dotnet ef migrations list
Sie können den Migrationsstatus auch programmgesteuert prüfen:
var allMigrations = context.Database.GetMigrations();
var appliedMigrations = await context.Database.GetAppliedMigrationsAsync();
var pendingMigrations = await context.Database.GetPendingMigrationsAsync();
GetPendingMigrationsAsync Vergleicht Migrationen in der konfigurierten Migrationsassembly mit den in der Zieldatenbank aufgezeichneten Migrationen. Es erkennt keine Modelländerungen, die in einer Migration nicht erfasst wurden. verwenden Sie dazu die nachstehende Überprüfung der ausstehenden Modelländerungen.
Überprüfen auf ausstehende Modelländerungen
Note
Dieses Feature wurde in EF Core 8.0 hinzugefügt.
Manchmal sollten Sie überprüfen, ob seit der letzten Migration Modelländerungen vorgenommen wurden. Dies kann Ihnen helfen, zu wissen, wann Sie oder ein Teamkollege vergessen haben, eine Migration hinzuzufügen. Eine Möglichkeit, dies zu tun, ist die Verwendung dieses Befehls.
dotnet ef migrations has-pending-model-changes
Sie können diese Überprüfung auch mithilfe von context.Database.HasPendingModelChanges() programmgesteuert durchführen. Dies kann verwendet werden, um einen Komponententest zu schreiben, der fehlschlägt, wenn Sie vergessen, eine Migration hinzuzufügen.
Note
Ab EF Core 9 führt der Aufruf von Migrate oder MigrateAsync bei ausstehenden Modelländerungen zu einer Ausnahme (Ereignis-ID PendingModelChangesWarning). Weitere Informationen finden Sie in der Dokumentation zum Anwenden von Migrationen und im Hinweis zu einer grundlegenden Änderung.
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 erfolgen, indem Sie den Ordner "Migrationen " löschen und Ihre Datenbank ablegen. An diesem Punkt können Sie eine neue anfängliche Migration erstellen, die Ihr gesamtes aktuelles Schema enthält.
Es ist auch möglich, alle Migrationen zurückzusetzen und eine einzelne zu erstellen, ohne Ihre Daten zu verlieren. Dies wird als Migrationen bezeichnet und umfasst einige manuelle Arbeit. EF Core stellt derzeit keinen automatisierten Befehl zur Verfügung; siehe dotnet/efcore#2174.
- 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 Migrations-Ordner.
- Erstellen Sie eine neue Migration, und generieren Sie dafür ein SQL-Skript (
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 sieht wie folgt aus (vergessen Sie nicht, die Werte zu aktualisieren):
INSERT INTO [__EFMigrationsHistory] ([MIGRATIONID], [PRODUCTVERSION])
VALUES (N'<full_migration_timestamp_and_name>', N'<EF_version>');
Warning
Jeder benutzerdefinierte Migrationscode geht verloren, wenn der Migrationsordner gelöscht wird. Alle Anpassungen müssen manuell auf die neue anfängliche Migration angewendet werden, um beibehalten zu werden.
Überprüfen Sie vor der Überprüfung, ob jede bereitgestellte Datenbank bei einer bekannten Migration vorhanden ist, und sichern Sie sie. Neue Datenbanken müssen aus der neuen anfänglichen Migration erstellt werden, während vorhandene Datenbanken die Ersetzungsmigration aufgezeichnet haben müssen, ohne Schemavorgänge auszuführen, die bereits angewendet wurden. Testen Sie beide Pfade vor der Bereitstellung.
Weitere Ressourcen
- Referenz zu Entity Framework Core-Tools – .NET CLI : Enthält Befehle zum Aktualisieren, Ablegen, Hinzufügen, Entfernen und vieles mehr.
- Referenz zu Entity Framework Core-Tools – Paket-Manager-Konsole in Visual Studio : Enthält Befehle zum Aktualisieren, Ablegen, Hinzufügen, Entfernen und vieles mehr.