Kommentar
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
När dina migreringar har lagts till måste de distribueras och tillämpas på dina databaser. Det finns olika strategier för att göra detta, där vissa är mer lämpliga för produktionsmiljöer och andra för utvecklingslivscykeln.
Note
Oavsett distributionsstrategi kontrollerar du alltid de genererade migreringarna och testar dem innan du tillämpar dem på en produktionsdatabas. En migrering kan släppa en kolumn när avsikten var att byta namn på den, eller misslyckas av olika skäl när den tillämpas på en databas.
Välj en distributionsstrategi
Använd ett migreringspaket för automatisk distribution. Ett paket är en distributionsartefakt som kan genereras i CI och köras senare utan .NET SDK, EF Core-verktygen eller programmets källkod. Använd ett SQL-skript i stället när SQL måste granskas, ändras, arkiveras eller överlämnas till en DBA innan det tillämpas.
För lokal utveckling, dotnet ef database update eller Update-Database är vanligtvis det enklaste alternativet. Aspire-projekt bör använda Aspire EF Core-migreringsintegrering för att samordna lokal migreringskörning och publicera paket eller skript.
| Strategi | Rekommenderad användning | Granska SQL före körning | Kräver SDK och källa vid körning | Använder EF-migreringslåsning | Kör EF-seedingdelegater |
|---|---|---|---|---|---|
| SQL-skript | DBA-kontrollerad eller granskad distribution | Yes | No | No | No |
| Migreringspaket | Automatiserad distribution | No | No | Yes | Yes |
| EF-kommandoradsverktyg | Lokal utveckling och testning | No | Yes | Yes | Yes |
| Körningsmigrering | Program som accepterar kompromisser med startmigrering | No | No | Yes | Yes |
EF Core 9 och senare använder migreringslåsning. Synkrona åtgärder och verktyg anropar UseSeeding; asynkrona åtgärder anropar UseAsyncSeeding.
Använd en separat identitet för distribution som har behörighet att ändra schemat. Den identitet som används av programmet vid körning bör normalt bara ha de behörigheter som programmet behöver för att läsa och skriva data.
SQL-skript
SQL-skript rekommenderas när distributionsprocessen kräver att den genererade SQL-filen inspekteras eller ändras före körningen. Fördelarna med den här strategin är följande:
- SQL-skript kan granskas för noggrannhet. Detta är viktigt eftersom det är en potentiellt farlig åtgärd att tillämpa schemaändringar på produktionsdatabaser som kan innebära dataförlust.
- I vissa fall kan skripten justeras så att de passar de specifika behoven i en produktionsdatabas.
- SQL-skript kan användas tillsammans med en distributionsteknik och kan även genereras som en del av din CI-process.
- SQL-skript kan tillhandahållas till en DBA och kan hanteras och arkiveras separat.
Grundläggande användning
Följande genererar ett SQL-skript från en tom databas till den senaste migreringen:
dotnet ef migrations script
Som standard skriver kommandot skriptet till standardutdata. Använd --output (eller -o) för att skapa en distributionsartefakt med ett förutsägbart namn:
dotnet ef migrations script --idempotent --output artifacts/migrations.sql
Från (till underförstått)
Följande genererar ett SQL-skript från den angivna migreringen till den senaste migreringen.
dotnet ef migrations script AddNewTables
Från och Till
Följande genererar ett SQL-skript från den angivna from migreringen till den angivna to migreringen.
dotnet ef migrations script AddNewTables AddAuditTable
Du kan använda en from som är nyare än to för att generera ett återställningsskript.
Warning
Observera potentiella dataförlustscenarier.
Skriptgenereringen accepterar följande två argument för att ange vilket migreringsintervall som ska genereras:
- Migreringen från till
ska vara den sista som tillämpas på databasen innan skriptet körs. Om inga migreringar har tillämpats anger du 0(detta är standardvärdet). - Migreringen från till är den sista migreringen som ska tillämpas på databasen efter att skriptet har körts. Detta är standardinställningen för den senaste migreringen i projektet.
Migreringsskript uppdaterar en befintlig databas. Etablera själva databasen via distributions- eller databasadministrationsprocessen för infrastrukturen innan skriptet tillämpas. Databasskapande kräver vanligtvis en annan anslutning, utökade behörigheter och providerspecifik konfiguration.
Idempotent SQL-skript
SQL-skripten som genereras ovan kan bara användas för att ändra schemat från en migrering till en annan. det är ditt ansvar att tillämpa skriptet på rätt sätt och endast på databaser i rätt migreringstillstånd. EF Core stöder också generering av idempotenta skript, som internt kontrollerar vilka migreringar som redan har tillämpats (via tabellen med migreringshistorik) och endast tillämpar saknade. Det här är användbart om du inte exakt vet vad den senaste migreringen som tillämpades på databasen var, eller om du distribuerar till flera databaser som var och en kan ha en annan migrering.
Stöd för Idempotent-skript beror på databasprovidern. SQLite stöder till exempel för närvarande inte generering av idempotent-migreringsskript.
Följande genererar idempotenta migreringar:
dotnet ef migrations script --idempotent
Kommandoradsverktyg
Ef-kommandoradsverktygen kan användas för att tillämpa migreringar på en databas. Även om den här metoden är produktiv för lokal utveckling och testning av migreringar är den inte idealisk för att hantera produktionsdatabaser:
- SQL-kommandona tillämpas direkt av verktyget, utan att ge utvecklaren en chans att inspektera eller ändra dem. Detta kan vara farligt i en produktionsmiljö.
- .NET SDK och EF-verktyget måste installeras på produktionsservrar och kräver projektets källkod.
Följande uppdaterar databasen till den senaste migreringen:
dotnet ef database update
Följande uppdaterar databasen till en angiven migrering:
dotnet ef database update AddNewTables
Observera också att detta kan användas för att gå tillbaka till en tidigare migrering.
Warning
Observera potentiella dataförlustscenarier.
Mer information om hur du tillämpar migreringar via kommandoradsverktygen finns i referensen EF Core-verktyg.
Miljö och konfiguration
Verktygen kör programkod för att konstruera DbContext. Leverantörsval, anslutningssträngar och modellkonfiguration kan därför vara beroende av programmiljön. EF Core design-time-verktyg använder Development miljön när varken ASPNETCORE_ENVIRONMENT eller DOTNET_ENVIRONMENT har angetts.
Ange miljön explicit när du genererar en distributionsartefakt och när du kör ett paket. Till exempel i PowerShell:
$env:ASPNETCORE_ENVIRONMENT = 'Production'
dotnet ef migrations bundle --output artifacts\efbundle.exe
$env:ASPNETCORE_ENVIRONMENT = 'Production'
.\efbundle.exe --connection $env:DEPLOYMENT_CONNECTION_STRING
Eller i ett POSIX-kompatibelt gränssnitt:
ASPNETCORE_ENVIRONMENT=Production \
dotnet ef migrations bundle --output artifacts/efbundle
ASPNETCORE_ENVIRONMENT=Production \
./efbundle --connection "$DEPLOYMENT_CONNECTION_STRING"
Detta förhindrar också att ett paket oväntat läser in användarhemligheter för utveckling. En säkrare standardmiljö för paket spåras av dotnet/efcore#36188. Miljöval i Visual Studio publiceringsmiljön spåras av dotnet/efcore#11950.
Lagra inte produktionsanslutningssträngar i källkontrollen eller bädda in dem i paketet. Ange distributionsanslutningen från distributionssystemets hemliga arkiv. Distributionsidentiteten bör ha schemabehörigheter. den normala programidentiteten bör vanligtvis inte göra det.
Bundles
Migreringspaket är exekverbara filer i en enda fil som kan användas för att tillämpa migreringar på en databas. De åtgärdar några av bristerna i SQL-skriptet och kommandoradsverktygen:
- För att köra SQL-skript krävs ytterligare verktyg.
- Beteendet för transaktionshantering och fortsätta vid fel för dessa verktyg är inkonsekvent och ibland oväntat. Detta kan lämna databasen i ett odefinierat tillstånd om ett fel inträffar vid tillämpning av migreringar.
- Paket kan genereras som en del av din CI-process och enkelt köras senare som en del av distributionsprocessen.
- Paket kan köras utan att installera .NET SDK eller EF Tool (eller till och med .NET Runtime, när de är fristående) och de kräver inte projektets källkod.
- Paket använder EF Cores migreringslåsning och kör konfigurerad
UseSeedinglogik.
Till skillnad från ett SQL-skript tillhandahåller ett paket för närvarande inte något sätt att inspektera den SQL som det kommer att köra eller lista de migreringar som det innehåller. Om distributionen kräver SQL-granskning genererar du ett skript i stället. Förbättringar av paketgranskning spåras av dotnet/efcore#25872.
Följande genererar ett paket:
dotnet ef migrations bundle --output artifacts/efbundle
Följande genererar ett fristående paket för Linux:
dotnet ef migrations bundle --self-contained --target-runtime linux-x64 --output artifacts/efbundle
Mer information om hur du skapar paket finns i referensen EF Core-verktyg.
efbundle
Den resulterande körbara filen heter efbundle som standard. Den kan användas för att uppdatera databasen till den senaste migreringen. Det motsvarar att köra dotnet ef database update eller Update-Database.
Arguments:
| Argument | Description |
|---|---|
<MIGRATION> |
Mål för migrering. Om "0" återställs alla migreringar. Standardinställningen är den sist utförda migreringen. |
Options:
| Option | Short | Description |
|---|---|---|
--connection <CONNECTION> |
Anslutningssträng till databasen. Använder standardinställningen som anges i AddDbContext eller OnConfiguring. | |
--verbose |
-v |
Visa utförliga utdata. |
--no-color |
Färglägga inte utdata. | |
--prefix-output |
Prefixutdata med nivå. |
I följande exempel tillämpas migreringar på en lokal SQL Server-instans med det angivna användarnamnet och autentiseringsuppgifterna:
.\efbundle.exe --connection 'Data Source=(local)\MSSQLSERVER;Initial Catalog=Blogging;User ID=myUsername;Password={;'$Credential;'here'}'
Om du vill återställa databasen skickar du den migrering som ska fortsätta att tillämpas. Genom att skicka 0 återställs alla migreringar:
.\efbundle.exe PreviousMigration --connection 'Data Source=(local)\MSSQLSERVER;Initial Catalog=Blogging;Integrated Security=True'
.\efbundle.exe 0 --connection 'Data Source=(local)\MSSQLSERVER;Initial Catalog=Blogging;Integrated Security=True'
Warning
En återställning kör åtgärder för Down varje migrering som är nyare än målet och kan leda till dataförlust. Granska och testa återställningsbeteendet innan du använder det på produktionsdata.
Konfigurerad seeding-kod körs efter en nedgradering. Det måste tolerera schemat för målmigreringen, inklusive ett programschema som saknas när målet är 0.
Warning
Om kontextkonfigurationen läser kopierar du de nödvändiga inställningsfilerna appsettings.jsontillsammans med paketet. Konfigurationsfiler löses från paketets körningskatalog. Placera inte produktionshemligheter i dessa filer. tillhandahålla dem via en säker konfigurationskälla eller alternativet --connection .
Containrar och distributionsjobb
Generera paketet under bygget och kör det som ett engångsdistributionsjobb när databasen är felfri. Installera inte SDK eller kör dotnet ef i programbilden och gör inte att alla programrepliker kör migreringar från dess startpunkt. Konfigurera distributionsplattformen att inte starta om migreringscontainern när den har avslutats.
För Aspire-program AddEFMigrations kan du samordna migreringar under lokal utveckling. Under publiceringen PublishAsMigrationBundle kan du generera ett paket eller en containeravbildning och PublishAsMigrationScript generera ett SQL-skript. Se Tillämpa EF Core-migreringar i Aspire för enstaka jobbkonfiguration för Azure Container Apps, Docker Compose och Kubernetes.
Exemplet på migreringspaketet visar två SQLite-migreringar, idempotent seeding, vidarebefordra program och återställningssäker seeding.
Exempel på migreringspaket
Ett paket behöver inkludera migreringar. Dessa skapas med hjälp av dotnet ef migrations add enligt beskrivningen i Skapa din första migrering. När du har migreringar redo att distribueras skapar du ett paket med hjälp av dotnet ef migrations bundle. Som exempel:
PS C:\local\AllTogetherNow\SixOh> dotnet ef migrations bundle
Build started...
Build succeeded.
Building bundle...
Done. Migrations Bundle: C:\local\AllTogetherNow\SixOh\efbundle.exe
PS C:\local\AllTogetherNow\SixOh>
Utdata är en körbar fil som passar ditt måloperativsystem. I mitt fall är detta Windows x64, så jag får en efbundle.exe placerad i min lokala mapp. Att köra denna körbara fil tillämpar de migreringar som finns i den.
PS C:\local\AllTogetherNow\SixOh> .\efbundle.exe
Applying migration '20210903083845_MyMigration'.
Done.
PS C:\local\AllTogetherNow\SixOh>
Precis som med dotnet ef database update eller Update-Databasetillämpas migreringar endast på databasen om de inte redan har tillämpats. Att köra samma paket igen gör till exempel ingenting, eftersom det inte finns några nya migreringar att tillämpa:
PS C:\local\AllTogetherNow\SixOh> .\efbundle.exe
No migrations were applied. The database is already up to date.
Done.
PS C:\local\AllTogetherNow\SixOh>
Men om ändringar görs i modellen och fler migreringar genereras med dotnet ef migrations addkan dessa paketeras till en ny körbar fil som är redo att tillämpas. Som exempel:
PS C:\local\AllTogetherNow\SixOh> dotnet ef migrations add SecondMigration
Build started...
Build succeeded.
Done. To undo this action, use 'ef migrations remove'
PS C:\local\AllTogetherNow\SixOh> dotnet ef migrations add Number3
Build started...
Build succeeded.
Done. To undo this action, use 'ef migrations remove'
PS C:\local\AllTogetherNow\SixOh> dotnet ef migrations bundle --force
Build started...
Build succeeded.
Building bundle...
Done. Migrations Bundle: C:\local\AllTogetherNow\SixOh\efbundle.exe
PS C:\local\AllTogetherNow\SixOh>
Tip
Alternativet --force kan användas för att skriva över det befintliga paketet med ett nytt.
När du kör det här nya paketet tillämpas dessa två nya migreringar på databasen:
PS C:\local\AllTogetherNow\SixOh> .\efbundle.exe
Applying migration '20210903084526_SecondMigration'.
Applying migration '20210903084538_Number3'.
Done.
PS C:\local\AllTogetherNow\SixOh>
Som standardinställning använder paketet anslutningssträngen från applikationens konfiguration. En annan databas kan dock migreras genom att skicka reťazec pripojenia på kommandoraden. Som exempel:
PS C:\local\AllTogetherNow\SixOh> .\efbundle.exe --connection "Data Source=(LocalDb)\MSSQLLocalDB;Database=SixOhProduction"
Applying migration '20210903083845_MyMigration'.
Applying migration '20210903084526_SecondMigration'.
Applying migration '20210903084538_Number3'.
Done.
PS C:\local\AllTogetherNow\SixOh>
Note
Den här gången tillämpades alla tre migreringarna, eftersom ingen av dem ännu hade tillämpats på produktionsdatabasen.
Tillämpa migreringar vid körning
Det är möjligt för själva programmet att tillämpa migreringar programmatiskt, vanligtvis under start. EF Core 9 och senare skyddar migreringskörningen med ett databasomfattande lås, så detta kan vara acceptabelt för program som föredrar enkel distribution och kan tolerera startmigreringsbeteende. Ett separat migreringsdistributionssteg är fortfarande att föredra när granskning, autentiseringsuppgifter med lägsta behörighet, samordnad distribution eller hög tillgänglighet är viktigt.
Överväg följande kompromisser:
- Om flera instanser av ditt program körs för versioner av EF före 9 kan båda programmen försöka tillämpa migreringen samtidigt och misslyckas (eller ännu värre, orsaka skada på data).
- På samma sätt kan detta orsaka allvarliga problem om ett program kommer åt databasen medan ett annat program migrerar den.
- Programmet måste ha förhöjd åtkomst för att ändra databasschemat. Det är vanligtvis bra att begränsa programmets databasbehörigheter i produktion.
- Det är viktigt att kunna återställa en tillämpad migrering i händelse av ett problem. De andra strategierna ger detta enkelt och utan krångel.
- SQL-kommandona tillämpas direkt av programmet, utan att ge utvecklaren en chans att inspektera eller ändra dem. Detta kan vara farligt i en produktionsmiljö.
Om du vill använda migreringar programmatiskt anropar du context.Database.MigrateAsync(). Ett typiskt ASP.NET program kan till exempel göra följande:
public static async Task Main(string[] args)
{
var host = CreateHostBuilder(args).Build();
using (var scope = host.Services.CreateScope())
{
var db = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
await db.Database.MigrateAsync();
}
host.Run();
}
Observera att MigrateAsync() bygger ovanpå IMigrator-tjänsten, som kan användas för mer avancerade scenarier. Använd myDbContext.GetInfrastructure().GetService<IMigrator>() för att komma åt den.
Warning
- Överväg noggrant innan du använder den här metoden i produktion. Föredra ett migreringspaket för automatisering eller ett SQL-skript när granskning och godkännande krävs.
- Anropa inte
EnsureCreatedAsync()innanMigrateAsync().EnsureCreatedAsync()kringgår migreringar för att skapa schemat, vilket gör attMigrateAsync()misslyckas.
Migreringslåsning
Börjar med EF Core 9 MigrateAsync och Migrate skaffar automatiskt ett databasomfattande lås innan migreringar tillämpas. Detta skyddar mot databasskada som kan uppstå på grund av flera programinstanser som kör migreringar samtidigt, vilket är ett vanligt scenario vid tillämpning av migreringar vid körning. Låset hålls under hela migreringsprocessen, inklusive eventuell seedingkod, och frigörs automatiskt när åtgärden har slutförts.
Migreringslåsning gäller när migreringar tillämpas med någon av följande metoder:
-
dotnet ef database update(.NET CLI) -
Update-Database(pakethanteringskonsolen) - Migreringspaket
- MigrateAsync och Migrate (körningsmigrering)
SQL-skript påverkas inte av migreringslåsning eftersom de tillämpas utanför EF Core.
Note
Från och med EF Core 9 kommer anrop av Migrate() eller MigrateAsync() att utlösa ett undantag när modellen har väntande ändringar jämfört med den senaste migreringen (varningshändelse-ID RelationalEventId.PendingModelChangesWarning). Använd kommandot dotnet ef migrations has-pending-model-changes i CI/CD-pipelinen för att upptäcka det här tillståndet före distribution. Varningen kan ignoreras via ConfigureWarnings (ignorera RelationalEventId.PendingModelChangesWarning) om det behövs, men detta rekommenderas vanligtvis inte i produktionsscenarier. Mer information finns i anteckningen om icke-bakåtkompatibla ändringar .
Warning
Låsningsmekanismen varierar avsevärt mellan databasprovidrar och kan omfatta providerspecifika problem. Till exempel använder SQLite-leverantören en låstabell som kan bli övergiven om processen avslutas oväntat. Se alltid leverantörens dokumentation för mer information.
Begränsningar
- Det går inte att omsluta MigrateAsync med en explicit transaktion. Mer information finns i Undantag utlöses när migreringar tillämpas i en explicit transaktion .
- På SQLite kan övergivna migreringslås blockera efterföljande migreringar.