Back to "Vous'Vous faites probablement une erreur dans les migrations de l’EF..."

This is a viewer only at the moment see the article on how this works.

To update the preview hit Ctrl-Alt-R (or ⌘-Alt-R on Mac) or Enter to refresh. The Save icon lets you save the markdown file to disk

This is a preview from the server running through my markdig pipeline

CI Entity Framework GitHub Migrations

Vous'Vous faites probablement une erreur dans les migrations de l’EF...

Tuesday, 27 October 2026

Mise à jour - 27 Octobre MSC2 Version originale a été publiée Nov 2025 - Correction des options de paquet et ajout d’une ligne directrice actuelle pour le noyau EF | 9/10 | Directives pour l’intégration à Aspire et indication claire des fonctionnalités de préview du Noyau ES |11 | Il n'y a pas d'erreurs dans l'échantillonnage. à la fin pour les corrections apportées à la version originale.

En cours MigrateAsync() au démarrage? VousM SK1 donnez votre schéma d’application-changez les permissions et vous espérez que rien ne va mal . Il y a une meilleure façon MSC4 Les paquets de migration EF vous permettent d’effectuer des migrations en tant qu’étape CI contrôléeMNK6 pour maintenir la sécurité de votre application de productionMMK7 Mais iciMRK8 c’est ce qui est le plus important MNK9 parfois, l’approche " erronéeMNK11 est vraiment bonneMDK12 Laissez MNK13 explorer quand utiliser chaque approcheMGK14

Documents officiels: Aperçu des migrations | Appliquer les migrations | Bundles

Le "Incorrect"La façon dont j’utilise le (

Ce blog utilise MigrateAsync() au début - l’approche que je vais vous dire de ne pas utiliser ' Je vais vous expliquer pourquoi ce n’est pas valable pour moi

Dans mon Program.cs dossier J’ai les renseignements suivants:

    using (var scope = app.Services.CreateScope())
    {
        var blogContext = scope.ServiceProvider.GetRequiredService<IMostlylucidDBContext>();
        await blogContext.Database.MigrateAsync();
    }

MigrateAsync() applique les migrations en suspens et crée la base de données si nécessaire. Simple M SK1 mais problématique:

  1. Dépendance de démarrage - Démarrage de la base de données ? La migration a échoué? Votre application est gagnéeM SK3 ne débute pas~.
  2. Permis élevés - Votre application a besoin des permissions DDL requises par ses migrations , incluant éventuellement les tableaux de déversement . Cela ne signifie pas nécessairement que le serveur SQL db_owner rôle, mais il est encore plus puissant que les demandes d’application ordinaires

Pourquoi m’en suis-je débarrassée: données publiques , réseau Docker uniqueM SK2 projet personnel. Vous pouvez probablement le faire.

Lorsque les migrations de temps d'exécution sont parfaites

  • Dev local - Cérémonie de battements d’itération rapide
  • Projets personnels - Radius d'explosion faibleM SK1 aucune donnée sensible
  • Docker-composer des environnements dev - La commodité gagne
  • Prototypage - Le schéma change constamment en tout état de cause

Quand ils ne sont pas

  • Instances multiples d'application - Les migrations de démarrage couplent chaque réplique au déploiement du schéma. EF Core 9+ ajoute le locking des migrationsM SK3 mais cela ne coordonne pas l'ancien code d'application avec un schéma en changement
  • Données sensibles - PIIM SK1 financier, réglementé = la séparation appropriée requise
  • Production avec des utilisateurs réels - Migration manquante = péril

La bonne voie: Bundles EF

Un paquet EF est exécutable contenant vos migrations compilées. Pensez dotnet ef database update packaged as a deployment artifact. It is framework-dependent by defaultM SK2 add --self-contained pour inclure le .NET runtime.

Pourquoi les paquets gagnent:

  • Aucun SDK ou EF CLI sur la cible - Un paquet comportant des fonctions autonomes - inclut également les dépendances natives .NET runtimeM SK3 OS/ qui sont encore applicables
  • Séparation appropriée - Une identité de déploiement distincte obtient les permissions requises pour le schéma ; l’application du temps d’exécution conserve ses droits de données normaux
  • Visibilité de l'IC - Les défauts apparaissent dans les registres des pipelines, ne sont pas enfouis au début de l'application
  • Porte de déploiement - Une sortie d’un paquet non zéro arrête le déploiement. Cela n’est pas une garantie que chaque changement de base de données a été reporté
  • Historique des migrations - Suivi des migrations qui ont été appliquées. SQL personnalisé et semis encore besoin d'un comportement de réessai attentif

Questions d'identité: Lorsque votre base de données le supporte, l'identité gérée peut supprimer les mots de passe stockés. Vous avez toujours besoin d'un réglage des connexions et d'une application distincte /autorisations de déploiementM SK3 Les Bundles fournissent un endroit pour faire en sorte que cette séparation soit exécutée

Exemple d'actions de GitHub

Inscrire un local dotnet-ef Le manifeste d'outils fixé à la version EF que vous utilisez, et incluant Microsoft.EntityFrameworkCore.Design dans le projet de démarrage. Le travail de construction rétablit les outils et crée l'artefact; le travail de déploiement protégé reçoit le secret de productionM SK2 Ces étapes prévoient un contrôle et la configuration appropriée .NET SDK est déjà établie

# Build job: no production credentials
- name: Restore EF tools
  run: dotnet tool restore

- name: Generate Linux migration bundle
  shell: bash
  run: |
    dotnet restore
    dotnet ef migrations bundle \
      --project Mostlylucid.DbContext \
      --startup-project Mostlylucid \
      --context MostlylucidDbContext \
      --configuration Release \
      --target-runtime linux-x64 \
      --self-contained \
      --output efbundle
  env:
    DOTNET_ENVIRONMENT: Production
    ASPNETCORE_ENVIRONMENT: Production

- uses: actions/upload-artifact@v4
  with:
    name: ef-migrations
    path: efbundle

# Deployment job: after downloading the same tested artifact
- uses: actions/download-artifact@v4
  with:
    name: ef-migrations

- name: Apply migrations
  shell: bash
  run: |
    chmod +x ./efbundle
    ./efbundle --connection "$MIGRATION_CONNECTION_STRING" --no-color --prefix-output
  env:
    DOTNET_ENVIRONMENT: Production
    ASPNETCORE_ENVIRONMENT: Production
    MIGRATION_CONNECTION_STRING: ${{ secrets.PROD_SQL_CONNECTIONSTRING }}

Utilisez votre nom de contexte réel. Choisir explicitement Production évite également le chargement accidentel de la configuration de développement . Design- La création du contexte en temps plein nécessite encore une configuration valide d’un fournisseurM SK3 Assurez-vous que vous n’êtes pas à produire si votre démarrage ou votre usine a besoin d’une chaîne de connexionMSC4 Il ne devrait pas être nécessaire de fournir des credentiales de production uniquement pour générer les migrations

Promouvoir le même artefact par l'entremise d'essais, Établissement et production. Utiliser un environnement GitHub protégé et serialiser les déploiements dans la même base de donnéesM SK2 Si la création du contexte lit des fichiers de configurations , expédier les fichiers non secrets requis avec le paquet aussiMSC4 Voir MicrosoftMST5s Directives sur le déploiement et la configuration.

Bundles locaux

Aucune CI? Vous voulez tester avant de pousser? Construire des paquets localementM SK2

Cases à utiliser: Essai avant CI, Délivrance du DBA M SK1 moi-même - comportant l'exe, aucun SDK requisMSC4 déploie d'essais de mise en place --verbose.

Création d'un paquet

# Once per repository: create a tool manifest if you do not already have one
dotnet new tool-manifest
# Example version: choose the supported patch matching your EF packages
dotnet tool install dotnet-ef --version 10.0.12
# In CI or after cloning
dotnet tool restore

# Basic bundle
dotnet ef migrations bundle \
    --project Mostlylucid.DbContext \
    --startup-project Mostlylucid \
    --output efbundle

# Self-contained (includes runtime for the selected OS/architecture)
dotnet ef migrations bundle \
    --project Mostlylucid.DbContext \
    --startup-project Mostlylucid \
    --output efbundle \
    --self-contained

# Cross-platform (e.g., build on Windows, deploy to Linux)
dotnet ef migrations bundle \
    --project Mostlylucid.DbContext \
    --startup-project Mostlylucid \
    --output efbundle \
    --target-runtime linux-x64

Faire fonctionner votre paquet

Voici l’utilisation d’un coque Unix. On Windows, build avec --output efbundle.exe et courir .\efbundle.exe dans PowerShell.

# Using the connection configured by your DbContext
./efbundle

# Override with a specific connection string
./efbundle --connection "$MIGRATION_CONNECTION_STRING"

# Or use an environment variable matching the key your context reads
export ConnectionStrings__DefaultConnection="$MIGRATION_CONNECTION_STRING"
./efbundle

Pour le dernier exemple dans PowerShell:

$env:ConnectionStrings__DefaultConnection = $env:MIGRATION_CONNECTION_STRING
.\efbundle.exe

Options utiles pour le Bundle

Il y a deux surfaces de commande différentes: dotnet ef migrations bundle b) Établissements la version exécutable; ./efbundle exécutions it. Leurs options ne sont pas interchangeables .

Au moment de la construction But
--output, -o Voie du fichier de sortie
--force, -f Remplacer un fichier de paquet existant
--self-contained Inclure le temps d'exécution .NET
--target-runtime, -r Déploiement RID, tel que linux-x64 ou linux-musl-x64
--project, --startup-project, --context Choisissez les migrations, configuration et contexte de démarrage
--configuration, --framework Choisissez la configuration de construction et le cadre cible
--no-build Réutiliser un up-àM SK2date de la mise en place du projet ; ne pas autoriser le regroupement des binaires anciens

Les outils ont également un --runtime option. Utiliser le paquet --target-runtime pour rendre le cible de déploiement explicite. Automne -Contrôlé ne signifie pas que l'on travaille un seul binaire sur Windows , Linux et macOSM SK3 bâtir pour la cible réelleMST4 incluant l'architecture et libcMSC5

./efbundle --help
./efbundle --version

# Apply pending migrations, with deployment-friendly logs
./efbundle --verbose --no-color --prefix-output

# Target is positional: this is NOT --target-migration
./efbundle 20231115_AddUserTable

# Revert everything: destructive, only for a disposable test database
./efbundle 0

Les supports exécutoires --connection, --verbose/-v, --no-color, --prefix-output, aide et versionM SK1 Son argument facultatif est la migration qui devrait rester appliquée. Le Source de commande du paquet EF montre le parteur réel.

Il n'y a pas de bourse à courir

./efbundle --dry-run Il s'agit d'une affaire qui n'a pas été réglée par la Cour. non pas existe. Il n’existe pas --verbose transformer l'exécution en vue préliminaire. Gérer SQL sans l'appliquer

dotnet ef migrations script PreviousMigration AddNewFeature \
    --project Mostlylucid.DbContext \
    --startup-project Mostlylucid \
    --output migrations.sql

Utilisation 0 comme le premier argument pour une nouvelle base de données. La génération des scripts n'essaie pas les contraintes à l'égard de vos données réelles . Une copie de base de datos restaurée, saine est là où vous trouvez ces problèmesM SK3

Pour voir les migrations du projet' et celles qui sont en suspens par rapport à la base de données configurée:

dotnet ef migrations list \
    --project Mostlylucid.DbContext \
    --startup-project Mostlylucid

Ajouter --no-connect pour lister les migrations de l'assemblage' sans communiquer avec la base de données ; qui ne peut pas vous dire quelles sont appliquées

Travail d'essai local

# 1. Create and inspect the migration
dotnet ef migrations add AddNewFeature \
    --project Mostlylucid.DbContext --startup-project Mostlylucid

# 2. Generate reviewable SQL for the expected starting point
dotnet ef migrations script PreviousMigration AddNewFeature \
    --project Mostlylucid.DbContext --startup-project Mostlylucid \
    --output migrations.sql

# 3. Build the bundle for this test host
dotnet ef migrations bundle \
    --project Mostlylucid.DbContext --startup-project Mostlylucid \
    --output efbundle --force

# 4. Apply to a disposable database or restored test copy
./efbundle --connection "$TEST_MIGRATION_CONNECTION_STRING" --verbose

# 5. Run again to verify migration history/retry behaviour
./efbundle --connection "$TEST_MIGRATION_CONNECTION_STRING"

Tester à la fois une base de données nouvelle et un amélioration d’une base de donnée existante représentative. qui fait l’exercice des changements du schémaM SK1 les contraintes et les données existantes avant la production .

Si la migration la plus récente a besoin de redéfinir et qu’elle n’a été appliquée que localement,, le premier mise à jour qui local de la base de données à PreviousMigration. Utilisez ensuite dotnet ef migrations remove avec le même projet/arguments de contexte. Retirer une source d’éditions migratoires ; il n’est pas une stratégie générale de retournement à la production

Élaborer des performances

La génération de paquets peut être lente, spécialement pour les cibles autochtonesM SK1contrôlées . Don' ne produit pas sur tous les bâtiments

  • Générer manuellement lors de l'essai local
  • Élaborer le paquet de diffusion dans CI et effectuer des vérifications de migration sur les PR
  • Cache à l'aide de toutes les entrées pertinentes: migrationsM SK1 modèle , configuration/ code d'usineMSC4 dépendances et RID cible

Si vous voulez vraiment auto-générationM SK1 ajouter un cible MSBuild:

<Target Name="BuildMigrationBundle">
  <Exec Command="dotnet ef migrations bundle --output $(OutputPath)efbundle.exe --force" />
</Target>

Then: dotnet build -t:BuildMigrationBundle

Approche hybride

Le meilleur des deux mondes: commodité locale , sécurité dans la productionM SK2

if (builder.Environment.IsDevelopment())
{
    using var scope = app.Services.CreateScope();
    var context = scope.ServiceProvider.GetRequiredService<IMostlylucidDBContext>();
    await context.Database.MigrateAsync();
}
// Production: CI pipeline runs the bundle

Solutions de rechange aux forfaits

Scripts SQL

Gérer un SQL simple au lieu d’un exécutable. Super pour l’examen du DBA et les processus de gestion des changements existants.

# All migrations
dotnet ef migrations script --output migrations.sql

# Idempotent: checks migration history, when supported by the provider
dotnet ef migrations script --idempotent --output migrations.sql

# Range of migrations
dotnet ef migrations script FromMigration ToMigration --output migrations.sql

Pros: Visibilité complète, tout client SQL peut le faire fonctionner , facile à contrôler les versions, flux de travail d’approbation du DBAM SK3

Cons: Votre coureur doit traiter correctement les défaillances, et un script de range assume la migration initiale attendue. Les scripts générés actualisent aussi l’historique des migrations EF ; --idempotent additionne des vérifications conditionnelles plutôt que d’inventer le suivi de l’histoire. SQLite ne supporte pas les scripts de migration idempotent.

Voir documents officiels sur les scripts SQL.

Les scripts SQL dans la CI

Pour SQL Server, faire failler les erreurs SQL dans le pipeline:

sqlcmd -S "$DB_SERVER" -d "$DB_NAME" -b -i migrations.sql

Pour PostgreSQL, faire la même chose explicitement:

psql --host="$DB_HOST" --username="$DB_USER" --dbname="$DB_NAME" \
    --set=ON_ERROR_STOP=1 --file=migrations.sql

Fournir des credentials par l'entremise du runner's mécanisme de sécurité supporté . Ces options sont pour le fournisseur qui a généré la SQL, et non deux commandes à exécuter contre la même base de donnéesM SK3 Voir sqlcmd et Traitement de l'erreur psql. Ne ajoutez pas blindement un autre enveloppeur de transactions : les scripts générés peuvent déjà gérer des opérations , et certaines opérations ne peuvent être exécutées à l’intérieur d’un seul envelopper.

DACPAC (Serveur SQL seulement)

DACPACs sont État- fondé non pas migration-basée. Vous définissez le schéma désiré, et SqlPackage le diffère par rapport à la base de données cibleM SK2

SqlPackage.exe /Action:Publish /SourceFile:MyDatabase.dacpac /TargetConnectionString:"..."

Pros: Système en tant que code, autoM SK1 génération de diffusions , couvrant les tableaux, vuesMSC4 procédures et indices stockésMNK5 outils d'entrepriseMRK6

Cons: SQL Server seulement, schéma en deux endroits M SK1 modèles EF + projet SQL), moteur diff fait des choix douteuxMSC4 renouvellement de colonnes ressemble à la chute

Voir Dossiers SqlPackage.

Tableau de comparaison

Approche Suivant le mieux pour MSC2 Exigences SMC3NET SMC4 Automne ESC5Traînes appliquées SSC6 DBA Friendly ISSC7 Cross ISC8Platform DB INSC9
MigrateAsync() DevM SK1petits projets Oui (temps d'exécution) M Oui
Bundles d’EF CIM SK2 Pipelines de CD SMC3 Non MSC4automne ESC5contenu USC6 USA7 Oui USA8 Un peu USC9 Oui
Scripts SQL DBA-environnements contrôlés MSC3 Non MSC4 Écrit l'historique MSc5 conditionnel avec --idempotent Oui Fournisseur
DACPAC Entreprise de serveur SQL MSC2 Pas de temps d'exécution EF MSC3 Comparaison du schéma MSc4 pas d'historique de l'EF SMC5 Oui SMC6 Non ESC7

Conseils

Le fichier du concepteur vous est arrivé

Les migrations fonctionnent localement, mais pas dans la CI? Vérifiez si vous avez engagé toutes les trois pièces générées:

  • 20231115_AddUserTable.cs - Code de migration
  • 20231115_AddUserTable.Designer.cs - Les métadonnées et le modèle cible de cette migration
  • BlogDbContextModelSnapshot.cs - Le snapshot du modèle actuel utilisé pour la planification de la prochaine migration

Les métadonnées manquantes du concepteur peuvent empêcher EF de découvrir la migration; une prise de vue manquante ou bloquée cause des diffs futurs inexacts. Il s'agit de fichiers différents avec des tâches différentesM SK2 Voir gestion des migrations.

Don't mélanger les stratégies de création: EnsureCreated() parpasse les migrations et leur histoire. Utilisez-le pour des bases de données disposables qui resteront sur cette stratégie MigrateAsync() et s’attend à ce que l’EF adopte le schéma qui en résulte. Lignes directrices pour la création de bases de données EF.

Contextes multiples de Db

dotnet ef migrations bundle --context BlogDbContext --output blog-migrations.exe
dotnet ef migrations bundle --context IdentityDbContext --output identity-migrations.exe

Priorité de la chaîne de connexion

Le paquet's --connection surride la connexion configurée pour le contexte. Autrement, la préséance appartient à votre application's configuration pipeline. Les variables environnementales par défaut de l’ASPM SK1NET Core builder, surrident JSON ,, mais les fournisseurs personnalisés ou une usine de conceptionMSC4time peuvent le changer.

ConnectionStrings__DefaultConnection ne fonctionne que si votre contexte lit réellement ConnectionStrings:DefaultConnection; le AdminSite__ConnectionString Les variables environnementales sont des entrées de configuration. Fournisseurs de configuration et commande.

IDesignTimeDbContextFactory

Les outils EF doivent instantaner votre DbContext. Si vous êtes dans un projet distinct ou si vous avez une mise en oeuvre complexe, IDesignTimeDbContextFactory<T>:

public class AdminDbContextFactory : IDesignTimeDbContextFactory<AdminDbContext>
{
    public AdminDbContext CreateDbContext(string[] args)
    {
        var config = new ConfigurationBuilder()
            .SetBasePath(Directory.GetCurrentDirectory())
            .AddJsonFile("appsettings.json", optional: true)
            .AddUserSecrets<AdminDbContextFactory>(optional: true)
            .AddEnvironmentVariables()
            .Build();

        var connectionString = config["AdminSite:ConnectionString"]
            ?? throw new InvalidOperationException("Missing connection string");

        var optionsBuilder = new DbContextOptionsBuilder<AdminDbContext>();
        optionsBuilder.UseSqlServer(connectionString, sql => sql.CommandTimeout(120));

        return new AdminDbContext(optionsBuilder.Options);
    }
}

Utilisez quand: DbContexte dans un projet distinctM SK1 démarrage complexe , ou création de contexte contrôlé pour l'outillage. EF utilise une usine découverte au lieu d'un démarrer normalMSC4 création fondée sur la baseMST5 incluant dans un paquetMSP6 Garder le fournisseurMSL7 modèle conforme à l'applicationMSR8 Cette usine minimale charge délibérément seulement les JSON de base MST9 secrets d'utilisateur facultatifs et variables environnementalesM ST10 ajouter l'environnement M ST11 fichiers spécifiques explicitement si nécessaire M S ST12 et garder les secrets de production hors de l'artéfactM S ST13 Les variables en milieu sont les dernières ici, de sorte que CI peut supprimer des secrets locaux M SP14

Ce qui a changé autour des migrations?

Le conseil de base survivant les nouvelles versions EF: bâtir un artefact répété et donner au déploiement du schéma sa propre identité. Mais plusieurs détails ont été améliorés depuis l’article initialM SK2

EF Core 9+: Locking, Checks de semis et de modèles

EF Core 9 introduit le locking de migration pour protéger l’exécution concurrente des migrations. Ce qui corrige une vieille race importante ; il ne rend pas un changement de schéma déstructif compatible avec les demandes encore en cours sur le code antérieur M SK3 Un déploiement séparé est toujours utile Écrasement de migration EF Core 9.

EF Core 9 commence également à rejeter l’application de migration lorsque le modèle a manqué des changements du snapshot.

dotnet ef migrations has-pending-model-changes \
    --project Mostlylucid.DbContext \
    --startup-project Mostlylucid

Cela vérifie Modèle versus photo instantanée, non si la production a appliqué toutes les migrations. Il n’est pas détecteur de dérive du schémaM SK2 Nondeterministe HasData valeurs telles que DateTime.Now ou Guid.NewGuid() peut produire des modifications répétées du modèle; les corriger plutôt que de supprimer la vérification. Changements de base EF 9.

UseSeeding et UseAsyncSeeding, introduit dans EF Core 9, fonctionne sous l'engrenage de migration. Les outils et les paquets utilisent le crochet synchroneM SK3 la mise en œuvre d'un seul paquet async est donc insuffisante. La sécheresse peut être exécutée même s'il n'y a pas de migrations en suspensMSC5 un deuxième paquet ne doit pas nécessairement fonctionner comme un nonMNK6opMRK7 Vérifier si les données existantes sont disponibles et faire en sorte que l'opération soit répétible. Le comportement de la semence.

EF Core 10: Nom de restriction par défaut pour les horloges

EF Core 10 est la version stable actuelle de LTS et requiert .NET 10. Une migrationM SK3l'ajout spécifique pour SQL Server est explicite par défaut-nomination des contraintesMSC5

modelBuilder.Entity<Blog>()
    .Property(b => b.Rating)
    .HasDefaultValue(3, "DF_Blog_Rating");

Il y a également modelBuilder.UseNamedDefaultConstraints(). En l’appuyant sur un modèle existant, la prochaine migration provoque le renouvellement de chaque contrainte par défaut dans ce modèle. Constraints par défaut désignés; Détails sur la diffusion de EF Core 10.

Aspire peut être propriétaire de l'orchestre

Aspire dispose maintenant d’une première ressource de migrations de la classe - dans Aspire.Hosting.EntityFrameworkCore. Dans un AppHost, le développement local peut exprimer directement la dépendance

var migrations = api.AddEFMigrations("api-migrations")
    .RunDatabaseUpdateOnStart();

api.WaitForCompletion(migrations);

RunDatabaseUpdateOnStart() est local-conduite d'exécutionM SK1 Pour la publication, PublishAsMigrationBundle() et PublishAsMigrationScript() produire des artefacts de déploiement; le paquet peut aussi être publié en tant que conteneur. Utiliser un seul emploiM SK2shot plutôt qu'un service permanent de restartingMSC3 Il s'agit d'une orchestration autour du même séparation de dépploiement Aspirer à l'intégration des migrations.

EF Core 11 Preview: Gardez ces fichiers séparés

À compter de cette mise à jour, EF Core 11 est encore en développement. La documentation actuelle comprend des fonctions qui ne sont pas des options EF Core 10:

  • .config/dotnet-ef.json fournit des défauts CLI répétés, comme le projet, le projet de démarrage et le contexteM SK1 les arguments explicites du CLI ont priorité.
  • dotnet ef migrations remove --offline supprime la dernière migration sans connexion à une base de données. Vous devez savoir qu'elle n'a pas été appliquée ; elle ne peut être combinée avec --force.
  • migrations remove --connection sélectionne explicitement la connexion de base de données.
  • dotnet ef database update AddFeature --add scaffolds, compile et applique une migration conjointement

Voir le version-labelled CLI reference et créer-et-appliquer la documentation. Pinnez vos outils plutôt qu’à supposer que toutes les options de la dernière page des dossiers existent dans votre version installée.

Quoi de neuf...?

Questions courantes et représailles I'ai reçu

" Pourquoi ne pas simplement courir dotnet ef database update dans CI?"

Obtenu ci-dessus, mais la version courte: les paquets sont des artefacts portatifs . Votre étape de déploiement n’est pas requiseM SK3 EF CLI ne vous est pas nécessaireMska4 code sourceMka5 ou designM Ska6 résolution du tempsMske7 Le même paquet fonctionne à l’essaiMKA8 stagingM KA9 et prod MSKA10 les mêmes migrations compiléesMsaka11 Configuration de connexion et déplacement réel de base de données doivent encore être vérifiésMkka12

"Isn'est-ce un surkill pour une petite application?

Peut-être . Si vous ' êtes seuls M SK2 les données sont publiques, et le rayon d'éruption est faible MigrateAsync() est bon. Mais le moment où vous ajoutez un deuxième développeur, données sensiblesM SK2 ou plusieurs environnements , les paquets payent pour eux-mêmes

"Qu'en est-il des rollbacks?

Une migration manquée bénéficie normalement de l’EF/gestion des transactions par le fournisseur , mais certaines opérations sont effectuées à l’extérieur des opérations.

  • Lancer le paquet avec une migration antérieure comme cible positionnelle. EF exécute les migrations plus récentes existantes' Down() méthodes; il n'y a pas de nouveau M SK1Migration descendante"
  • Restore une sauvegarde testée lorsque les données doivent être récupérées
  • Rédiger et déployer une nouvelle migration corrective

Retourner une colonne défectueuse ne rétablit pas son contenu. Examen et essai Down() Juste aussi soigneusement que Up().

Pour les systèmes essentiels: essai des migrations contre un clone de base de données d’abord.

" Puis-je effectuer des migrations dans un conteneur Kubernetes init?

Un conteneur init peut faire fonctionner un paquet, mais il fonctionne une fois par poud, pas une fois par déploiement. Pour les charges de travail de production répétées , préférer une migration dédiée Job avec un port de déploiementM SK3 Pour un seul exemple de pot

initContainers:
  - name: migrate
    image: myapp:latest
    command: ["./efbundle"]
    env:
      - name: ConnectionStrings__Default
        valueFrom:
          secretKeyRef:
            name: db-secrets
            key: connection-string

Le conteneur d'application attend l'achèvement de l'init avec succès. L'image doit contenir le paquet Linux et sa configuration requise ; utiliser ici une identité distincte pour la migration, non pas l'app' les credentials réguliers.

"Qu'en pense-t-on du FluentMigrator ?

Ils fonctionnent très bien. Les paquets EF sont la solution initiale de l’EF - mais FluentMigrator et DbUp avoir leurs ventilateurs. Difference clé : c’est la migration-outils spécifiquesM SK3 tandis que les paquets EF proviennent de votre modèle d’EF existant

" mon DBA veut revoir tous les SQL avant de le faire fonctionner

Utilisation --idempotent scripts:

dotnet ef migrations script --idempotent --output migrations.sql

DBA examine et approuve. Si l’approbation est pour la SQL exacte, exécuter que le script révisé et l’archiver avec la mise à jour. Un paquet génère SQL au moment de l’exécution et peut aussi exécuter un code d’ensemencement configuré ; il n’est pas une enveloppe d’exécution pour votre fichier approuvé

"Comment puis-je gérer les migrations avec un temps d'arrêt zéro?

Il s’agit là d’une question de stratégie de déploiement, et non d’un problème de migration.

  1. Expand the schema with changes the old app can tolerate, such as a new nullable column
  2. Mettre en place un code qui gère la transition, y compris les écritures doubles au besoin
  3. Remplir les données existantes et les vérifier
  4. Changer les lectures et les contraintes une fois que le code et les données sont prêts
  5. Contrat ultérieur, supprimer les anciennes colonnes seulement après que l'ancienne instance a été déversée

Les trousses ne permettent pas de résoudre ce problème - elles offrent une façon contrôlée d’effectuer les étapes du schéma . Durée du bouclage

L'Errata

La version originale comprenait plusieurs commandes incorrectes et certaines allégations trop larges. Ces dernières sont corrigées ci-dessus ; ce document indique ce qui a changé.

  • Il n'y a pas de courbe à sec. efbundle --dry-run n'est pas supporté. Générer un script SQL pour l'examen, puis tester contre une base de données disponible ou une copie récupérée --verbose encore exécute les migrations.
  • La migration cible est positionnelle. Utilisation efbundle PreviousMigration, non --target-migration. Cible 0 renverser toutes les migrations en exécutant leurs Down() méthodes.
  • Self-contained is opt-inM SK2 Un paquet par défaut a toujours besoin d’une version compatible .NET runtime. --self-contained inclut pour un RID; il ne supprime pas les dépendances natives de l’OS/ .
  • Les permissions de schéma ne sont pas synonymes avec db_owner. Donner à l’identité de déploiement les permissions requises par ses migrations, plutôt que d’admettre un rôle SQL particulier
  • Une passerelle de déploiement n’est pas une récupération automatique. Un paquet défectueux arrête le déploiement, mais les transactions-les opérations affaiblies et la perte de données ont besoin d’un plan de récupération propre . Le retrait d’une migration de source n’est pas un ralentissement de production
  • Le concepteur n’est pas le coupe-feuille. Commit the migration, its .Designer.cs les métadonnées et le snapshot du modèle de contexte distinct.
  • Les scripts suivent les migrations. Historique de migration des mises à jour SQL générée. --idempotent additionne des vérifications pour les migrations déjà effectuées-AppliquéeSupport de ; dépend du fournisseur, et SQLite ne peut pas générer ces scriptsM SK3
  • La configuration de la connexion est l’application-définie. Les variables environnementales n'affectent la connexion que si le contexte/fabrication lit la clé correspondante. L'exemple de fabrication permet maintenant aux variables d'environnement de supprimer les secrets des utilisateurs facultatifs.
  • Le blocage des migrations modifie l’avis de coïncidence. EF Core 9+ protège l'exécution de migration avec un dispositif d'engrenage. Il ne coordonne pas les demandes en direct ni rend les modifications du schéma qui se détruisent plus sûres pour les anciennes versions des applicationsM SK2
  • Un conteneur d’entrée est par pot. Il ne s’agit pas d’un emploi de migration unique.
  • Un paquet n’execute pas votre fichier SQL examiné. Lorsque l’approbation couvre une SQL exacte, déploie que les artifacts . Bundles peuvent aussi faire fonctionner des semis configurés, y compris lorsqu’il n’y a pas de migrationsM SK3

Les nouveaux éléments du noyau EF 11 sont marqués séparément par des étiquettes de preview.

logo

© 2026 Scott Galloway — Unlicense — All content and source code on this site is free to use, copy, modify, and sell.