Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
À mesure que votre modèle change, les migrations sont ajoutées et supprimées dans le cadre du développement normal, et les fichiers de migration sont archivés dans le contrôle de code source de votre projet. Pour gérer les migrations, vous devez d’abord installer les outils en ligne de commande EF Core.
Tip
Si le DbContext fichier se trouve dans un assembly différent du projet de démarrage, vous pouvez spécifier explicitement les projets cibles et de démarrage dans les outils de console du Gestionnaire de package ou les outils CLI .NET.
Ajouter une migration
Une fois votre modèle modifié, vous pouvez ajouter une migration pour cette modification :
dotnet ef migrations add AddBlogCreatedTimestamp
Le nom de la migration peut être utilisé comme un message de validation dans un système de contrôle de version. Par exemple, vous pouvez choisir un nom tel que AddBlogCreatedTimestamp si la modification est une nouvelle CreatedTimestamp propriété sur votre Blog entité.
Trois fichiers sont ajoutés à votre projet sous le répertoire Migrations :
-
XXXXXXXXXXXXXX_AddBlogCreatedTimestamp.cs-Le fichier de migration principal. Contient les opérations nécessaires pour appliquer la migration (in
Up) et la rétablir (inDown). - XXXXXXXXXXXXXX_AddBlogCreatedTimestamp.Designer.cs--Le fichier de métadonnées des migrations. Contient des informations utilisées par EF.
- MyContextModelSnapshot.cs-Un instantané de votre modèle actuel. Permet de déterminer ce qui a changé lors de l’ajout de la migration suivante.
L’horodatage dans le nom de fichier permet de les conserver chronologiquement afin que vous puissiez voir la progression des modifications.
Namespaces
Vous êtes libre de déplacer les fichiers de migration et de modifier leur espace de noms manuellement. Les migrations sont créées en tant que sœurs de la dernière migration. Vous pouvez également spécifier le répertoire au moment de la génération comme suit :
dotnet ef migrations add InitialCreate --output-dir Your/Directory
Note
Vous pouvez également modifier l’espace de noms indépendamment du répertoire à l’aide de --namespace.
Créer et appliquer une migration en une seule étape
Note
Cette fonctionnalité a été ajoutée dans EF Core 11.
La dotnet ef database update commande prend en charge la création et l’application d’une migration en une seule étape à l’aide de l’option --add . Cela utilise Roslyn pour compiler la migration au moment de l’exécution, ce qui permet d’activer des scénarios tels que des applications .NET Aspire et conteneurisées où l’application ne peut pas être arrêtée et reconstruite :
dotnet ef database update InitialCreate --add
Les mêmes options disponibles pour dotnet ef migrations add peuvent être utilisées :
dotnet ef database update AddProducts --add --output-dir Migrations/Products --namespace MyApp.Migrations
Cette commande génère une nouvelle migration avec le nom spécifié, la compile à l’aide de Roslyn et l’applique immédiatement à la base de données. Les fichiers de migration sont toujours enregistrés sur le disque pour le contrôle de code source et la recompilation ultérieure.
Si aucune modification de modèle en attente n’est détectée, la commande applique toutes les migrations en attente existantes sans en créer une nouvelle.
Personnaliser le code de migration
Bien qu’EF Core crée généralement des migrations précises, vous devez toujours passer en revue le code et vous assurer qu’il correspond à la modification souhaitée ; dans certains cas, il est même nécessaire de le faire.
Renommages de colonne
L’un des exemples notables où la personnalisation des migrations est requise consiste à renommer une propriété. Par exemple, si vous renommez une propriété Name vers FullName, EF Core génère la migration suivante :
migrationBuilder.DropColumn(
name: "Name",
table: "Customers");
migrationBuilder.AddColumn<string>(
name: "FullName",
table: "Customers",
nullable: true);
EF Core est généralement incapable de savoir quand l’intention consiste à supprimer une colonne et à en créer une (deux modifications distinctes) et quand une colonne doit être renommée. Si la migration ci-dessus est appliquée as-is, tous vos noms de clients sont perdus. Pour renommer une colonne, remplacez la migration générée ci-dessus par les éléments suivants :
migrationBuilder.RenameColumn(
name: "Name",
table: "Customers",
newName: "FullName");
Tip
Le processus de structuration de migration vous avertit quand une opération peut entraîner une perte de données (par exemple la suppression d’une colonne). Si vous voyez cet avertissement, veillez particulièrement à passer en revue le code des migrations pour obtenir une précision.
Opérations de données
Les migrations peuvent déplacer des données et modifier le schéma. Choisissez l’opération selon que les valeurs sont connues lorsque la migration est écrite :
- Utilisez
InsertData,UpdateDataet pour les valeurs fixes etDeleteDatales lignes identifiées par des clés explicites. EF Core traduit ces opérations en SQL spécifique au fournisseur, de sorte qu’elles fonctionnent également lors de la génération de scripts et d’offres groupées. - Utilisez
Sqlquand les nouvelles valeurs doivent être calculées à partir des données de base de données existantes. La syntaxe SQL peut différer selon le fournisseur ; branche surMigrationBuilder.ActiveProviderle cas échéant. - Définissez une opération de migration personnalisée lorsqu’une opération réutilisable a besoin d’une génération SQL spécifique au fournisseur.
N’utilisez pas les types CLR actuels DbContext ou d’entité pour déplacer des données dans une migration. Les migrations historiques doivent continuer à compiler et à se comporter de la même façon une fois ces types modifiés ou supprimés.
Transformer des données existantes
Lorsque vous remplacez des colonnes, conservez les données sources jusqu’à ce que la destination ait été remplie :
- Ajoutez la colonne de destination comme nullable.
- Remplissez-la à partir des colonnes existantes.
- Faites en sorte que la colonne de destination soit requise, le cas échéant.
- Supprimez les colonnes sources.
La migration suivante implémente cette séquence pour SQL Server et 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");
Ajoutez une branche pour chaque fournisseur pris en charge par l’application. La levée d’un fournisseur inconnu est plus sûre que l’application silencieuse d’une migration incomplète. Ne générez pas SQL à partir de valeurs non approuvées ; la migration SQL est exécutée avec des privilèges de modification de schéma.
Certaines transformations ne peuvent pas être inversées sans perdre des informations. Implémentez Down uniquement lorsque les valeurs d’origine peuvent être reconstruites en toute sécurité. Sinon, échouez explicitement et exigez la restauration des données à partir d’une sauvegarde dans le cadre de la procédure de restauration.
Insérer des données fixes
Utilisez InsertData quand les clés et les valeurs sont connues lorsque la migration est écrite :
migrationBuilder.InsertData(
table: "Countries",
columns: new[] { "CountryId", "Name" },
values: new object[,]
{
{ 1, "United States" },
{ 2, "Canada" }
});
La méthode correspondante Down doit appeler DeleteData avec les mêmes clés.
Mettre à jour les données fixes
UpdateData identifie une ligne par sa clé et définit une ou plusieurs colonnes sur des valeurs fixes :
migrationBuilder.UpdateData(
table: "Countries",
keyColumn: "CountryId",
keyValue: 1,
column: "Name",
value: "United States of America");
La Down méthode doit restaurer les valeurs précédentes.
Supprimer des données fixes
DeleteData identifie également les lignes par clé :
migrationBuilder.DeleteData(
table: "Countries",
keyColumn: "CountryId",
keyValue: 2);
Si la suppression doit être réversible, la Down méthode doit être utilisée InsertData pour restaurer chaque valeur supprimée. Ces opérations ne interrogent pas l’état actuel de la base de données ; utiliser Sql ou initialiser l’amorçage au moment où le comportement dépend des données existantes.
Modifications arbitraires via SQL brut
Sql brut peut également être utilisé pour gérer les objets de base de données dont EF Core n’est pas conscient. Pour ce faire, ajoutez une migration sans apporter de modification de modèle ; une migration vide est générée, que vous pouvez ensuite remplir avec les opérations SQL brutes.
Par exemple, la migration suivante crée une procédure stockée SQL Server :
migrationBuilder.Sql(
@"
EXEC ('CREATE PROCEDURE getFullName
@LastName nvarchar(50),
@FirstName nvarchar(50)
AS
SELECT @LastName + @FirstName;')");
Tip
EXEC est utilisé lorsqu’une instruction doit être la première ou une seule dans un lot SQL. Il peut également être utilisé pour contourner les erreurs d’analyseur dans les scripts de migration idempotent qui peuvent se produire lorsque des colonnes référencées n’existent pas actuellement sur une table.
Cela peut être utilisé pour gérer n’importe quel aspect de votre base de données, notamment :
- Procédures stockées
- Recherche en texte intégral
- Functions
- Triggers
- Views
Dans la plupart des cas, EF Core encapsule automatiquement chaque migration dans sa propre transaction lors de l’application des migrations. Malheureusement, certaines opérations de migration ne peuvent pas être effectuées dans une transaction dans certaines bases de données ; pour ces cas, vous pouvez refuser la transaction en passant suppressTransaction: true à migrationBuilder.Sql.
Note
Dans EF Core 9, EF Core s’étend sur toutes les migrations en attente avec une transaction unique par défaut (cette opération a été rétablie dans EF Core 10). Pour plus d’informations, consultez la note de modification cassant .
Supprimer une migration
Parfois, vous ajoutez une migration et vous réalisez que vous devez apporter des modifications supplémentaires à votre modèle EF Core avant de l’appliquer. Pour supprimer la dernière migration, utilisez cette commande.
dotnet ef migrations remove
Après avoir supprimé la migration, vous pouvez apporter les modifications supplémentaires au modèle et l’ajouter à nouveau.
Warning
Évitez de supprimer les migrations qui ont déjà été appliquées aux bases de données de production. Cela signifie que vous ne pourrez pas rétablir ces migrations à partir des bases de données et peut interrompre les hypothèses effectuées par les migrations suivantes.
Si la migration a été appliquée localement
Pour une base de données de développement jetable, commencez par mettre à jour la base de données vers la migration précédente, puis supprimez la migration du projet. Utilisez 0 comme cible lors de la suppression de la première migration.
dotnet ef database update PreviousMigration
dotnet ef migrations remove
--force Vous pouvez également effectuer les deux étapes :
dotnet ef migrations remove --force
Si la migration a été appliquée à une base de données partagée
Ne supprimez pas une migration qui a été appliquée à une base de données partagée, de test ou de production. En règle générale, conservez la migration dans le projet et ajoutez une nouvelle migration corrective. Si une restauration planifiée est requise, exécutez la restauration pendant que le code de migration d’origine est toujours disponible et coordonnez le déploiement de l’application et de la base de données.
Supprimer une migration nonappliée plus ancienne
Les outils suppriment uniquement la dernière migration. Ne supprimez pas une migration au milieu de la séquence et modifiez manuellement l’instantané du modèle. Si la migration et chaque migration après qu’elle n’est pas publiée et nonappliée, supprimez les migrations ultérieures dans l’ordre inverse, supprimez la migration indésirable, puis créez à nouveau la structure du modèle conservé.
Si les migrations ont été créées sur différentes branches, suivez plutôt le flux de travail de l’arborescence de migration divergente .
Liste des migrations
Vous pouvez répertorier toutes les migrations existantes comme suit :
dotnet ef migrations list
Vous pouvez également inspecter l’état de migration par programmation :
var allMigrations = context.Database.GetMigrations();
var appliedMigrations = await context.Database.GetAppliedMigrationsAsync();
var pendingMigrations = await context.Database.GetPendingMigrationsAsync();
GetPendingMigrationsAsync compare les migrations dans l’assembly de migrations configuré avec les migrations enregistrées dans la base de données cible. Il ne détecte pas les modifications de modèle qui n’ont pas été capturées dans une migration ; utilisez la vérification des modifications de modèle en attente ci-dessous.
Vérifier si des modifications de modèle sont en attente
Note
Cette fonctionnalité a été ajoutée dans EF Core 8.0.
Parfois, vous souhaiterez peut-être vérifier s’il y a eu des modifications apportées au modèle depuis la dernière migration. Cela peut vous aider à savoir quand vous ou un collègue avez oublié d’ajouter une migration. Pour ce faire, utilisez cette commande.
dotnet ef migrations has-pending-model-changes
Vous pouvez également effectuer cette vérification par programmation à l’aide context.Database.HasPendingModelChanges()de . Cela peut être utilisé pour écrire un test unitaire qui échoue lorsque vous oubliez d’ajouter une migration.
Note
À partir d’EF Core 9, l’appel de Migrate ou de MigrateAsync en présence de modifications du modèle en attente lève une exception (ID d’événement PendingModelChangesWarning). Pour plus d’informations, consultez la documentation sur l’application des migrations et la note sur le changement majeur.
Réinitialisation de toutes les migrations
Dans certains cas extrêmes, il peut être nécessaire de supprimer toutes les migrations et de recommencer. Cela peut être facilement effectué en supprimant votre dossier Migrations et en supprimant votre base de données ; à ce stade, vous pouvez créer une migration initiale, qui contiendra l’intégralité de votre schéma actuel.
Il est également possible de réinitialiser toutes les migrations et de créer un seul sans perdre vos données. C’est ce que l’on appelle les migrations de courge et implique un travail manuel. EF Core ne fournit actuellement pas de commande de squashing automatisée ; voir dotnet/efcore#2174.
- Sauvegardez votre base de données, en cas de problème.
- Dans votre base de données, supprimez toutes les lignes de la table d’historique des migrations (par exemple,
DELETE FROM [__EFMigrationsHistory]sur SQL Server). - Supprimez votre dossier Migrations .
- Créez une migration et générez un script SQL pour celui-ci (
dotnet ef migrations script). - Insérez une seule ligne dans l’historique des migrations pour enregistrer que la première migration a déjà été appliquée, car vos tables sont déjà là. L’insertion SQL est la dernière opération du script SQL généré ci-dessus et ressemble à ce qui suit (n’oubliez pas de mettre à jour les valeurs) :
INSERT INTO [__EFMigrationsHistory] ([MIGRATIONID], [PRODUCTVERSION])
VALUES (N'<full_migration_timestamp_and_name>', N'<EF_version>');
Warning
Tout code de migration personnalisé est perdu lorsque le dossier Migrations est supprimé. Toutes les personnalisations doivent être appliquées manuellement à la nouvelle migration initiale afin d’être conservées.
Avant de courge, vérifiez que chaque base de données déployée se trouve à une migration connue et sauvegardez-la. De nouvelles bases de données doivent être créées à partir de la nouvelle migration initiale, tandis que les bases de données existantes doivent avoir la migration de remplacement enregistrée sans exécuter d’opérations de schéma qui ont déjà été appliquées. Testez les deux chemins avant le déploiement.
Ressources supplémentaires
- Informations de référence sur les outils Entity Framework Core - .NET CLI : inclut des commandes pour mettre à jour, supprimer, ajouter, retirer et bien plus encore.
- Documentation de référence des outils Entity Framework Core - Console du Gestionnaire de packages dans Visual Studio : inclut des commandes pour mettre à jour, supprimer, ajouter, retirer et bien plus encore.