Vous'Vous faites probablement une erreur dans les migrations de l’EF...
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:
- 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~.
- 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_ownerrô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 migration20231115_AddUserTable.Designer.cs- Les métadonnées et le modèle cible de cette migrationBlogDbContextModelSnapshot.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égieMigrateAsync()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.jsonfournit 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 --offlinesupprime 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 --connectionsélectionne explicitement la connexion de base de données.dotnet ef database update AddFeature --addscaffolds, 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.
- Expand the schema with changes the old app can tolerate, such as a new nullable column
- Mettre en place un code qui gère la transition, y compris les écritures doubles au besoin
- Remplir les données existantes et les vérifier
- Changer les lectures et les contraintes une fois que le code et les données sont prêts
- 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-runn'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--verboseencore exécute les migrations. - La migration cible est positionnelle. Utilisation
efbundle PreviousMigration, non--target-migration. Cible0renverser toutes les migrations en exécutant leursDown()méthodes. - Self-contained is opt-inM SK2 Un paquet par défaut a toujours besoin d’une version compatible .NET runtime.
--self-containedinclut 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.csles 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.
--idempotentadditionne 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.