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
Sunday, 23 November 2025
Τρέξιμο MigrateAsync() Υπάρχει ένας καλύτερος τρόπος - τα πακέτα μετανάστευσης EF σας επιτρέπουν να εκτελέσετε τις μεταναστεύσεις ως ένα ελεγχόμενο βήμα CI, κρατώντας την εφαρμογή παραγωγής σας ασφαλή. Αλλά εδώ είναι το θέμα: μερικές φορές ο "λάθος" τρόπος είναι πραγματικά μια χαρά. Ας εξερευνήσουμε πότε να χρησιμοποιήσουμε κάθε προσέγγιση.
Επίσημα έγγραφα: Επισκόπηση των μεταναστευτικών ροών | Εφαρμογή των Μεταναστών | ΜπάντλςCity name (optional, probably does not need a translation)
Αυτό το blog χρησιμοποιεί MigrateAsync() Κατά την εκκίνηση - η προσέγγιση που είμαι έτοιμος να σας πω να μην χρησιμοποιήσετε . Εδώ είναι γιατί αυτό είναι εντάξει για μένα , και γιατί πιθανώς δεν είναι για εσάς .
Στο Program.cs αρχείο Έχω τα ακόλουθα:
using (var scope = app.Services.CreateScope())
{
var blogContext = scope.ServiceProvider.GetRequiredService<IMostlylucidDBContext>();
await blogContext.Database.MigrateAsync();
}
MigrateAsync() εφαρμόζει εν αναμονή της μετανάστευσης και δημιουργεί τη βάση δεδομένων, εάν χρειάζεται. Απλό - αλλά προβληματικό:
db_owner Μόλις έδωσες στην εφαρμογή σου τα κλειδιά για να πετάξεις τραπέζια.Γιατί τη γλιτώνω: δημόσια δεδομένα, ενιαίο δίκτυο Ντόκερ, προσωπικό έργο. Μάλλον δεν μπορείς.
Ένα πακέτο EF είναι ένα αυτόνομο εκτελέσιμο που περιέχει τις συγκεντρωμένες μεταναστεύσεις σας. dotnet ef database update συσκευάζεται σε ένα αυτόνομο .exe.
Γιατί τα πακέτα κερδίζουν:
db_owner; μόνο CI runner κάνει, μόνο κατά τη διάρκεια της ανάπτυξηςΣημείωση: Για ασφάλεια ποιότητας παραγωγής, χρήση Διαχειριζόμενη Ταυτότητα Αλλά οι δέσμες εξακολουθούν να είναι ένα σημαντικό βήμα προς τα πάνω από τις μεταναστεύσεις runtime.
- name: Install EF Core tools
run: dotnet tool install --global dotnet-ef
- name: Add EF tools to PATH
run: echo "$HOME/.dotnet/tools" >> $GITHUB_PATH
- name: Generate EF migration bundle
run: |
dotnet ef migrations bundle \
--project ${{ env.WEB_PROJECT }} \
--output efbundle.exe \
--configuration ${{ env.BUILD_CONFIGURATION }} \
--runtime ${{ env.RUNTIME_IDENTIFIER }} \
--context AdminDbContext \
env:
AdminSite__ConnectionString: ${{ secrets.PROD_SQL_CONNECTIONSTRING }}
- name: Run EF migration bundle
run: |
./efbundle.exe
env:
AdminSite__ConnectionString: ${{ secrets.PROD_SQL_CONNECTIONSTRING }}
Το πακέτο διαβάζει συμβολοσειρές σύνδεσης από τις περιβαλλοντικές μεταβλητές και εφαρμόζει εν αναμονή των μεταναστευτικών ροών.
Δεν υπάρχει πληροφοριοδότης; Θέλετε να δοκιμάσετε πριν σπρώξετε; Φτιάξτε δέσμες τοπικά.
Χρήση περιπτώσεων: Δοκιμή πριν από CI, DBA παράδοση (αυτοσυντηρούμενη exe, δεν χρειάζεται SDK), ανάπτυξη stage, αποσφαλμάτωση με --verbose.
# Install EF CLI (once)
dotnet tool install --global dotnet-ef
# Basic bundle
dotnet ef migrations bundle \
--project Mostlylucid.DbContext \
--startup-project Mostlylucid \
--output efbundle.exe
# Self-contained (includes runtime - portable to machines without .NET)
dotnet ef migrations bundle \
--project Mostlylucid.DbContext \
--startup-project Mostlylucid \
--output efbundle.exe \
--self-contained
# Cross-platform (e.g., build on Windows, deploy to Linux)
dotnet ef migrations bundle \
--project Mostlylucid.DbContext \
--startup-project Mostlylucid \
--output efbundle \
--runtime linux-x64
# Using default connection string from appsettings.json
./efbundle.exe
# Override with a specific connection string
./efbundle.exe --connection "Host=localhost;Database=mostlylucid;Username=postgres;Password=secret"
# Using an environment variable (matches your config key)
$env:ConnectionStrings__DefaultConnection="Host=localhost;..." # PowerShell
export ConnectionStrings__DefaultConnection="Host=localhost;..." # Bash
./efbundle.exe
# See what migrations would be applied without running them
./efbundle.exe --dry-run
# Verbose output for debugging
./efbundle.exe --verbose
# Apply migrations up to a specific migration (useful for testing)
./efbundle.exe --target-migration "20231115_AddUserTable"
# Combine options
./efbundle.exe --verbose --dry-run
# 1. Create migration
dotnet ef migrations add AddNewFeature \
--project Mostlylucid.DbContext \
--startup-project Mostlylucid
# 2. Build bundle
dotnet ef migrations bundle \
--project Mostlylucid.DbContext \
--startup-project Mostlylucid \
--output efbundle.exe
# 3. Dry run first
./efbundle.exe --dry-run --verbose
# 4. Run for real
./efbundle.exe --verbose
# 5. Broken? Remove and retry
dotnet ef migrations remove \
--project Mostlylucid.DbContext \
--startup-project Mostlylucid
Σφάλματα σύνταξης αλιευμάτων, παραβιάσεις περιορισμών, θέματα FK - όλα πριν ΚΚΠ ή παραγωγή.
Η γενιά Bundle είναι αργή - 30+ δευτερόλεπτα σε μεγάλα έργα.
Αν θέλετε πραγματικά αυτό-γενιά, προσθέστε ένα MSBuild στόχο:
<Target Name="BuildMigrationBundle">
<Exec Command="dotnet ef migrations bundle --output $(OutputPath)efbundle.exe --force" />
</Target>
Τότε: dotnet build -t:BuildMigrationBundle
Οι καλύτεροι και από τους δύο κόσμους: ευκολία τοπικά, ασφάλεια στην παραγωγή.
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
Δημιουργήστε απλό SQL αντί για εκτελέσιμο. Μεγάλη για αναθεώρηση DBA και τις υπάρχουσες διαδικασίες διαχείρισης αλλαγών.
# All migrations
dotnet ef migrations script --output migrations.sql
# Idempotent (safe to run multiple times) - USE THIS
dotnet ef migrations script --idempotent --output migrations.sql
# Range of migrations
dotnet ef migrations script FromMigration ToMigration --output migrations.sql
Pros: Πλήρης ορατότητα, κάθε πελάτης SQL μπορεί να το τρέξει, φιλική έκδοση ελέγχου, DBA ροή εργασίας έγκριση.
Κατά: Δεν υπάρχει αυτόματη παρακολούθηση (χρήση) --idempotent), χειρωνακτική εκτέλεση, πιθανή μετατόπιση εάν τα σενάρια τροποποιούνται.
Βλέπεις; επίσημα έγγραφα σχετικά με τα σενάρια SQL.
- name: Generate and apply migrations
run: |
dotnet ef migrations script --idempotent --output migrations.sql
# SQL Server
sqlcmd -S ${{ secrets.DB_SERVER }} -d ${{ secrets.DB_NAME }} -i migrations.sql
# Or PostgreSQL
PGPASSWORD=${{ secrets.DB_PASSWORD }} psql -h ${{ secrets.DB_HOST }} -f migrations.sql
ΔΑΚΑΚ είναι κρατικής βάσης Όχι, όχι. με βάση τη μετανάστευση. Μπορείτε να καθορίσει το επιθυμητό σχήμα, και SqlPackage diffs αυτό στη βάση δεδομένων στόχου.
SqlPackage.exe /Action:Publish /SourceFile:MyDatabase.dacpac /TargetConnectionString:"..."
Pros: Schema ως κώδικας, παραγωγή auto-diff, χειρίζεται τα πάντα (τραπέζια, απόψεις, SPs, ευρετήρια), εργαλεία επιχειρήσεων.
Κατά: SQL Server μόνο, schema σε δύο θέσεις (EF μοντέλα + SQL έργο), diff κινητήρα κάνει αμφισβητήσιμες επιλογές, στήλη μετονομάσεις μοιάζουν με drop+add.
Βλέπεις; SqlPackage docs.
Η προσέγγιση είναι η καλύτερη για την χρήση .NET Αυτόματες tracks Εφαρμοσμένες DBA Friendly _ DBA Friendly Cross-platform DB
|----------|----------|---------------|---------------------|--------------|-------------------|
| MigrateAsync() Ναι, ναι, ναι, ναι, όχι, ναι, ναι, ναι, ναι, ναι, ναι, ναι, ναι.
Ναι, ναι, ναι, ναι, ναι, ναι.
SQL Scripts DBA-ελεγχόμενα περιβάλλοντα --idempotent Ναι, ναι, ναι, ναι, ναι, ναι, ναι.
Ναι (βασισμένο στο κράτος) Ναι, ναι, ναι, όχι, όχι, όχι, όχι.
Οι μεταναστεύσεις δουλεύουν τοπικά αλλά όχι στον πληροφοριοδότη; Έλεγξες και τα δύο αρχεία:
20231115_AddUserTable.cs - Ο κώδικας μετανάστευσης20231115_AddUserTable.Designer.cs - Το μοντέλο στιγμιότυποΛείπει το αρχείο Designer = σιωπηλή αποτυχία.
dotnet ef migrations bundle --context BlogDbContext --output blog-migrations.exe
dotnet ef migrations bundle --context IdentityDbContext --output identity-migrations.exe
--connection επιχείρημαappsettings.jsonΧρήση μεταβλητών περιβάλλοντος σε CI.
Εάν το DbContext σας βρίσκεται σε ξεχωριστό έργο ή έχει περίπλοκη εκκίνηση, εφαρμόστε το IDesignTimeDbContextFactory<T>:
public class AdminDbContextFactory : IDesignTimeDbContextFactory<AdminDbContext>
{
public AdminDbContext CreateDbContext(string[] args)
{
var config = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: true)
.AddEnvironmentVariables()
.AddUserSecrets<AdminDbContextFactory>()
.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);
}
}
Χρήση όταν: DbContext σε ξεχωριστό έργο, περίπλοκη εκκίνηση, χρειάζονται μυστικά χρηστών για το σχεδιασμό-χρόνο.
Συνηθισμένες ερωτήσεις και αναπηδήσεις που έλαβα.
dotnet ef database update στην CI;"Καλύπτεται παραπάνω, αλλά η σύντομη έκδοση: τα πακέτα είναι φορητά αντικείμενα. Το βήμα ανάπτυξής σας δεν χρειάζεται EF CLI, πηγαίο κώδικα, ή ανάλυση σχεδιασμού-χρόνου.
Αν είσαι μόνος, τα δεδομένα είναι δημόσια και η ακτίνα έκρηξης είναι χαμηλή... MigrateAsync() Αλλά τη στιγμή που θα προσθέσετε ένα δεύτερο προγραμματιστή, ευαίσθητα δεδομένα, ή πολλαπλά περιβάλλοντα, πακέτα πληρώνουν για τον εαυτό τους.
Η EF δεν κάνει αυτόματα rollbacks.
Down() μετανάστευση και να το τρέξει (αλλά θα πρέπει να έχετε γράψει)Για τα κρίσιμα συστήματα: δοκιμή μετανάστευσης κατά ενός κλώνου βάσης δεδομένων πρώτα.
Ναι. Το δοχείο Bundle + init είναι ένα συμπαγές μοτίβο:
initContainers:
- name: migrate
image: myapp:latest
command: ["./efbundle.exe"]
env:
- name: ConnectionStrings__Default
valueFrom:
secretKeyRef:
name: db-secrets
key: connection-string
Το δοχείο App περιμένει να ολοκληρωθεί το init.
Τα πακέτα EF είναι η ιθαγενή λύση EF, αλλά FluentMigrator και DbUpName έχουν τους οπαδούς τους. Βασική διαφορά: αυτά είναι εργαλεία ειδικά για τη μετανάστευση, ενώ τα πακέτα EF προέρχονται από το υπάρχον μοντέλο EF σας.
Χρήση --idempotent σενάρια:
dotnet ef migrations script --idempotent --output migrations.sql
DBA κριτικές και εγκρίνει. Στη συνέχεια είτε:
Αυτό είναι ζήτημα στρατηγικής ανάπτυξης, όχι ζήτημα μετανάστευσης.
Οι bundles δεν το λύνουν αυτό - απλά κάνουν το 3ο βήμα πιο προβλέψιμο.
© 2026 Scott Galloway — Unlicense — All content and source code on this site is free to use, copy, modify, and sell.