Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
Zodra uw migraties zijn toegevoegd, moeten ze worden geïmplementeerd en toegepast op uw databases. Er zijn verschillende strategieën om dit te doen, waarbij sommige beter geschikt zijn voor productieomgevingen en andere voor de ontwikkelingslevenscyclus.
Note
Ongeacht uw implementatiestrategie controleert u altijd de gegenereerde migraties en test u deze voordat u deze toepast op een productiedatabase. Een migratie kan een kolom verwijderen wanneer de naam van de kolom is gewijzigd of kan om verschillende redenen mislukken wanneer deze wordt toegepast op een database.
Een implementatiestrategie kiezen
Gebruik een migratiebundel voor geautomatiseerde implementatie. Een bundel is een implementatieartefact dat kan worden gegenereerd in CI en later kan worden uitgevoerd zonder de .NET SDK, de EF Core-hulpprogramma's of de broncode van de toepassing. Gebruik in plaats daarvan een SQL-script wanneer de SQL moet worden gecontroleerd, gewijzigd, gearchiveerd of doorgegeven aan een DBA voordat deze wordt toegepast.
Voor lokale ontwikkeling, dotnet ef database update of Update-Database is meestal de eenvoudigste optie. Streven-projecten moeten de integratie van De Aspire EF Core-migraties gebruiken om de uitvoering van lokale migraties te coördineren en bundels of scripts te publiceren.
| Strategy | Aanbevolen gebruik | SQL controleren vóór uitvoering | Vereist SDK en bron bij uitvoering | Maakt gebruik van EF-migratievergrendeling | Voert EF-seeding-gemachtigden uit |
|---|---|---|---|---|---|
| SQL-script | DBA-beheerde of door controle gecontroleerde implementatie | Yes | No | No | No |
| Migratiebundel | Geautomatiseerde implementatie | No | No | Yes | Yes |
| EF-opdrachtregelprogramma's | Lokale ontwikkeling en testen | No | Yes | Yes | Yes |
| Runtimemigratie | Toepassingen die de opstartmigratie accepteren | No | No | Yes | Yes |
EF Core 9 en hoger maken gebruik van migratievergrendeling. Synchrone bewerkingen en hulpprogramma's aanroepen UseSeeding; asynchrone bewerkingen aanroepen UseAsyncSeeding.
Gebruik een afzonderlijke identiteit voor implementatie die gemachtigd is om het schema te wijzigen. De identiteit die tijdens de uitvoering door de toepassing wordt gebruikt, moet normaal gesproken alleen beschikken over de machtigingen die de toepassing nodig heeft om gegevens te lezen en te schrijven.
SQL-scripts
SQL-scripts worden aanbevolen wanneer het implementatieproces vereist dat de gegenereerde SQL vóór de uitvoering wordt geïnspecteerd of gewijzigd. De voordelen van deze strategie zijn onder andere:
- SQL-scripts kunnen worden gecontroleerd op nauwkeurigheid; dit is belangrijk omdat het toepassen van schemawijzigingen op productiedatabases een potentieel gevaarlijke bewerking is waarbij gegevens verloren kunnen gaan.
- In sommige gevallen kunnen de scripts worden afgestemd op de specifieke behoeften van een productiedatabase.
- SQL-scripts kunnen worden gebruikt in combinatie met een implementatietechnologie en kunnen zelfs worden gegenereerd als onderdeel van uw CI-proces.
- SQL-scripts kunnen worden verstrekt aan een DBA en kunnen afzonderlijk worden beheerd en gearchiveerd.
Basisgebruik
Hieronder wordt een SQL-script gegenereerd van een lege database naar de meest recente migratie:
dotnet ef migrations script
Standaard schrijft de opdracht het script naar standaarduitvoer. Gebruik --output (of -o) om een implementatieartefact te maken met een voorspelbare naam:
dotnet ef migrations script --idempotent --output artifacts/migrations.sql
Met "van naar" (impliciet)
Hieronder wordt een SQL-script gegenereerd van de opgegeven migratie naar de meest recente migratie.
dotnet ef migrations script AddNewTables
Met 'Van' en 'Naar'
Hieronder wordt een SQL-script gegenereerd van de opgegeven from migratie naar de opgegeven to migratie.
dotnet ef migrations script AddNewTables AddAuditTable
U kunt een from gebruiken die nieuwer is dan de to om een terugdraaiscript te genereren.
Warning
Noteer mogelijke scenario's voor gegevensverlies.
Het genereren van scripts accepteert de volgende twee argumenten om aan te geven welk bereik van migraties moet worden gegenereerd:
- De van migratie moet de laatste migratie zijn die op de database is toegepast voordat het script wordt uitgevoerd. Als er geen migraties zijn toegepast, geeft u
0op (dit is de standaardinstelling). - De voor migratie is de laatste migratie die wordt toegepast op de database nadat het script is uitgevoerd. Dit wordt standaard ingesteld op de laatste migratie in uw project.
Migratiescripts werken een bestaande database bij. Richt de database zelf in via uw infrastructuurimplementatie of databasebeheerproces voordat u het script toepast. Het maken van een database vereist doorgaans een andere verbinding, verhoogde machtigingen en providerspecifieke configuratie.
Idempotent SQL-scripts
De hierboven gegenereerde SQL-scripts kunnen alleen worden toegepast om uw schema te wijzigen van de ene migratie naar de andere; het is uw verantwoordelijkheid om het script op de juiste manier toe te passen en alleen op databases met de juiste migratiestatus. EF Core ondersteunt ook het genereren van idempotent scripts, die intern controleren welke migraties al zijn toegepast (via de geschiedenistabel van migraties) en alleen ontbrekende scripts toepassen. Dit is handig als u niet precies weet wat de laatste migratie is die op de database is toegepast, of als u implementeert in meerdere databases die mogelijk bij een andere migratie zijn.
Ondersteuning voor Idempotent scripts is afhankelijk van de databaseprovider. SQLite biedt bijvoorbeeld momenteel geen ondersteuning voor het genereren van idempotent migratiescripts.
Met het volgende worden idempotente migraties gegenereerd:
dotnet ef migrations script --idempotent
Opdrachtregelprogramma's
De EF-opdrachtregelprogramma's kunnen worden gebruikt om migraties toe te passen op een database. Hoewel u productief bent voor lokale ontwikkeling en het testen van migraties, is deze benadering niet ideaal voor het beheren van productiedatabases:
- De SQL-opdrachten worden rechtstreeks door het hulpprogramma toegepast, zonder dat de ontwikkelaar deze kan inspecteren of wijzigen. Dit kan gevaarlijk zijn in een productieomgeving.
- De .NET SDK en het EF-hulpprogramma moeten worden geïnstalleerd op productieservers en vereist de broncode van het project.
Met de volgende updates wordt uw database bijgewerkt naar de nieuwste migratie:
dotnet ef database update
Met de volgende updates wordt uw database bijgewerkt naar een bepaalde migratie:
dotnet ef database update AddNewTables
Houd er rekening mee dat dit ook kan worden gebruikt om terug te keren naar een eerdere migratie.
Warning
Noteer mogelijke scenario's voor gegevensverlies.
Zie de EF Core-hulpprogramma'svoor meer informatie over het toepassen van migraties via de opdrachtregelprogramma's.
Omgeving en configuratie
De hulpprogramma's voeren toepassingscode uit om de DbContext. Selectie van providers, verbindingsreeksen en modelconfiguratie kan daarom afhankelijk zijn van de toepassingsomgeving. Ef Core ontwerptijd tooling maakt gebruik van de Development omgeving wanneer noch DOTNET_ENVIRONMENTASPNETCORE_ENVIRONMENT is ingesteld.
Stel de omgeving expliciet in bij het genereren van een implementatieartefact en bij het uitvoeren van een bundel. Bijvoorbeeld in PowerShell:
$env:ASPNETCORE_ENVIRONMENT = 'Production'
dotnet ef migrations bundle --output artifacts\efbundle.exe
$env:ASPNETCORE_ENVIRONMENT = 'Production'
.\efbundle.exe --connection $env:DEPLOYMENT_CONNECTION_STRING
Of in een POSIX-compatibele shell:
ASPNETCORE_ENVIRONMENT=Production \
dotnet ef migrations bundle --output artifacts/efbundle
ASPNETCORE_ENVIRONMENT=Production \
./efbundle --connection "$DEPLOYMENT_CONNECTION_STRING"
Hiermee voorkomt u ook dat een bundel gebruikersgeheimen voor ontwikkeling onverwacht laadt. Een veiligere standaardomgeving voor bundels wordt bijgehouden door dotnet/efcore#36188. Omgevingsselectie in de Visual Studio publicatie-ervaring wordt bijgehouden door dotnet/efcore#11950.
Sla geen productieverbindingsreeksen op in broncodebeheer of sluit ze in de bundel in. Geef de implementatieverbinding op vanuit het geheime archief van het implementatiesysteem. De implementatie-identiteit moet schemamachtigingen hebben; de normale toepassingsidentiteit mag meestal niet.
Bundles
Migratiebundels zijn uitvoerbare bestanden met één bestand die kunnen worden gebruikt om migraties toe te passen op een database. Ze pakken enkele van de tekortkomingen van het SQL-script en opdrachtregelprogramma's aan:
- Voor het uitvoeren van SQL-scripts zijn extra hulpprogramma's vereist.
- De transactieafhandeling en het doorgaan-bij-fouten gedrag van deze hulpprogramma's zijn inconsistent en soms onverwacht. Hierdoor kan uw database een niet-gedefinieerde status hebben als er een fout optreedt bij het toepassen van migraties.
- Bundels kunnen worden gegenereerd als onderdeel van uw CI-proces en kunnen later eenvoudig worden uitgevoerd als onderdeel van uw implementatieproces.
- Bundels kunnen worden uitgevoerd zonder de .NET SDK of EF Tool te installeren (of zelfs de .NET Runtime, indien zelfstandig) en ze hebben de broncode van het project niet nodig.
- Bundels gebruiken de migratievergrendeling van EF Core en voeren geconfigureerde logica uit
UseSeeding.
In tegenstelling tot een SQL-script biedt een bundel momenteel geen manier om de SQL te inspecteren die wordt uitgevoerd of vermeld de migraties die het bevat. Als voor uw implementatie SQL-controle is vereist, genereert u in plaats daarvan een script. Verbeteringen in bundelinspectie worden bijgehouden door dotnet/efcore#25872.
Met het volgende wordt een bundel gegenereerd:
dotnet ef migrations bundle --output artifacts/efbundle
Met het volgende wordt een zelfstandige bundel voor Linux gegenereerd:
dotnet ef migrations bundle --self-contained --target-runtime linux-x64 --output artifacts/efbundle
Raadpleeg de EF Core-hulpprogramma'svoor meer informatie over het maken van bundels.
efbundle
Het resulterende uitvoerbare bestand heet standaard efbundle. Deze kan worden gebruikt om de database bij te werken naar de meest recente migratie. Het is gelijk aan het uitvoeren van dotnet ef database update of Update-Database.
Arguments:
| Argument | Description |
|---|---|
<MIGRATION> |
De doelmigratie. Als de waarde '0' is, worden alle migraties teruggezet. Standaard ingesteld op de laatste migratie. |
Options:
| Option | Short | Description |
|---|---|---|
--connection <CONNECTION> |
De verbindingsreeks voor de database. Standaard ingesteld op de waarde die is opgegeven in AddDbContext of OnConfiguring. | |
--verbose |
-v |
Uitgebreide uitvoer weergeven. |
--no-color |
Kleur de uitvoer niet. | |
--prefix-output |
Voorzie de uitvoer van een voorvoegsel met niveau. |
In het volgende voorbeeld worden migraties toegepast op een lokaal SQL Server exemplaar met behulp van de opgegeven gebruikersnaam en referenties:
.\efbundle.exe --connection 'Data Source=(local)\MSSQLSERVER;Initial Catalog=Blogging;User ID=myUsername;Password={;'$Credential;'here'}'
Als u de database wilt terugdraaien, geeft u de migratie door die moet worden toegepast. Als u alle migraties doorgeeft 0 , worden alle migraties hersteld:
.\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
Met een terugdraaiactie worden de Down bewerkingen van elke migratie uitgevoerd die hoger is dan het doel en kan leiden tot gegevensverlies. Controleer het terugdraaigedrag en test het terugdraaien voordat u deze op productiegegevens gebruikt.
Geconfigureerde seeding-code wordt uitgevoerd na een downgrade. Het moet het schema van de doelmigratie tolereren, inclusief een ontbrekend toepassingsschema wanneer het doel is 0.
Warning
Als de contextconfiguratie wordt gelezen, kopieert appsettings.jsonu de vereiste instellingenbestanden naast de bundel. Configuratiebestanden worden opgelost vanuit de uitvoeringsmap van de bundel. Plaats geen productiegeheimen in deze bestanden; leveren via een beveiligde configuratiebron of de --connection optie.
Containers en implementatietaken
Genereer de bundel tijdens de build en voer deze uit als een eenmalige implementatietaak nadat de database in orde is. Installeer de SDK niet of voer dotnet ef deze uit in de installatiekopieën van de toepassing en voer niet elke toepassingsreplica migraties uit vanaf het toegangspunt. Configureer het implementatieplatform om de migratiecontainer niet opnieuw op te starten nadat deze is afgesloten.
Voor Aspire-toepassingen AddEFMigrations kunt u migraties coördineren tijdens lokale ontwikkeling. Tijdens het publiceren PublishAsMigrationBundle kunt u een bundel of een containerinstallatiekopieën verzenden en PublishAsMigrationScript een SQL-script verzenden. Zie EF Core-migraties toepassen in Aspire voor een taakconfiguratie met één shot voor Azure Container Apps, Docker Compose en Kubernetes.
Het voorbeeld van de migratiebundel demonstreert twee SQLite-migraties, idempotent seeding, forward application en rollback-safe seeding.
Voorbeeld van migratiebundel
Voor een bundel moeten migraties worden opgenomen. Deze worden gemaakt met behulp van dotnet ef migrations add zoals beschreven in Uw eerste migratie maken. Zodra u migraties klaar hebt om te implementeren, maakt u een bundel met behulp van de dotnet ef migrations bundle. Voorbeeld:
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>
De uitvoer is een uitvoerbaar bestand dat geschikt is voor het beoogde besturingssysteem. In mijn geval is dit Windows x64, dus ik krijg een efbundle.exe gedropt in mijn lokale map. Als u dit uitvoerbare bestand uitvoert, worden de migraties hierin toegepast:
PS C:\local\AllTogetherNow\SixOh> .\efbundle.exe
Applying migration '20210903083845_MyMigration'.
Done.
PS C:\local\AllTogetherNow\SixOh>
Net als bij dotnet ef database update of Update-Databaseworden migraties alleen toegepast op de database als ze nog niet zijn toegepast. Als u dezelfde bundel bijvoorbeeld opnieuw uitvoert, gebeurt er niets, omdat er geen nieuwe migraties zijn die moeten worden toegepast:
PS C:\local\AllTogetherNow\SixOh> .\efbundle.exe
No migrations were applied. The database is already up to date.
Done.
PS C:\local\AllTogetherNow\SixOh>
Als er echter wijzigingen worden aangebracht in het model en er meer migraties worden gegenereerd met dotnet ef migrations add, kunnen deze worden gebundeld in een nieuw uitvoerbaar bestand dat kan worden toegepast. Voorbeeld:
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
De optie --force kan worden gebruikt om de bestaande bundel te overschrijven met een nieuwe bundel.
Als u deze nieuwe bundel uitvoert, worden deze twee nieuwe migraties toegepast op de database:
PS C:\local\AllTogetherNow\SixOh> .\efbundle.exe
Applying migration '20210903084526_SecondMigration'.
Applying migration '20210903084538_Number3'.
Done.
PS C:\local\AllTogetherNow\SixOh>
De bundel maakt standaard gebruik van de database verbindingsreeks uit de configuratie van uw toepassing. Een andere database kan echter worden gemigreerd door de verbindingsreeks door te geven op de opdrachtregel. Voorbeeld:
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
Deze keer werden alle drie de migraties toegepast, omdat ze nog niet waren toegepast op de productiedatabase.
Migraties tijdens runtime toepassen
Het is mogelijk dat de toepassing zelf programmatisch migraties toepast, meestal tijdens het opstarten. EF Core 9 en hoger beschermen migratie-uitvoering met een databasebrede vergrendeling, zodat dit acceptabel kan zijn voor toepassingen die de voorkeur geven aan eenvoudige implementatie en het gedrag van opstartmigratie kan verdragen. Een afzonderlijke migratie-implementatiestap heeft nog steeds de voorkeur wanneer de referenties voor minimale bevoegdheden, gecoördineerde implementatie of hoge beschikbaarheid worden beoordeeld.
Houd rekening met de volgende compromissen:
- Voor versies van EF vóór 9, als er meerdere exemplaren van uw toepassing worden uitgevoerd, kunnen beide toepassingen proberen de migratie gelijktijdig toe te passen en te mislukken (of erger, leiden tot beschadiging van gegevens).
- Als een toepassing toegang heeft tot de database terwijl een andere toepassing deze migreert, kan dit ernstige problemen veroorzaken.
- De toepassing moet verhoogde toegang hebben om het databaseschema te wijzigen. Het is over het algemeen een goede gewoonte om de databasemachtigingen van de toepassing in productie te beperken.
- Het is belangrijk om een toegepaste migratie terug te draaien in geval van een probleem. De andere strategieën bieden dit gemakkelijk en kant-en-klare.
- De SQL-opdrachten worden rechtstreeks door het programma toegepast, zonder de ontwikkelaar de kans te geven om ze te inspecteren of te wijzigen. Dit kan gevaarlijk zijn in een productieomgeving.
Als u migraties programmatisch wilt toepassen, roept u context.Database.MigrateAsync()aan. Een typische ASP.NET toepassing kan bijvoorbeeld het volgende doen:
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();
}
Houd er rekening mee dat MigrateAsync() is gebaseerd op de IMigrator-service, die kan worden gebruikt voor geavanceerdere scenario's. Gebruik myDbContext.GetInfrastructure().GetService<IMigrator>() om er toegang toe te krijgen.
Warning
- Overweeg zorgvuldig voordat u deze benadering in productie gebruikt. Geef de voorkeur aan een migratiebundel voor automatisering of een SQL-script wanneer beoordeling en goedkeuring vereist zijn.
- Bel
EnsureCreatedAsync()niet voorMigrateAsync().EnsureCreatedAsync()migraties omzeilt om het schema te maken, waardoorMigrateAsync()mislukt.
Migratievergrendeling
Beginnend met EF Core 9 MigrateAsync en Migrate automatisch een databasebrede vergrendeling verkrijgen voordat u migraties toepast. Dit beschermt tegen beschadiging van de database die kan voortvloeien uit meerdere toepassingsexemplaren die gelijktijdig migraties uitvoeren. Dit is een veelvoorkomend scenario bij het toepassen van migraties tijdens runtime. De vergrendeling wordt bewaard voor de duur van de migratieuitvoering, inclusief eventuele seeding-code, en wordt automatisch vrijgegeven wanneer de bewerking is voltooid.
Migratievergrendeling is van toepassing wanneer migraties worden toegepast met behulp van een van de volgende methoden:
-
dotnet ef database update(.NET CLI) -
Update-Database(Pakketbeheerconsole) - Migratiebundels
- MigrateAsync en Migrate (runtime-migratie)
SQL-scripts worden niet beïnvloed door migratievergrendeling, omdat ze buiten EF Core worden toegepast.
Note
Vanaf EF Core 9 leidt het aanroepen van Migrate() of MigrateAsync() tot een uitzondering wanneer het model openstaande wijzigingen heeft ten opzichte van de laatste migratie (waarschuwings-id RelationalEventId.PendingModelChangesWarning). Als u deze voorwaarde wilt detecteren vóór de implementatie, gebruikt u de dotnet ef migrations has-pending-model-changes opdracht in uw CI/CD-pijplijn. De waarschuwing kan worden onderdrukt via ConfigureWarnings (negeren RelationalEventId.PendingModelChangesWarning) indien nodig, maar dit wordt over het algemeen niet aanbevolen in productiescenario's. Zie de belangrijke wijzigingsnotitie voor meer informatie.
Warning
Het vergrendelingsmechanisme varieert aanzienlijk tussen databaseproviders en kan betrekking hebben op providerspecifieke problemen. De SQLite-provider maakt bijvoorbeeld gebruik van een vergrendelingstabel die kan worden afgebroken als het proces onverwacht wordt beëindigd. Raadpleeg altijd de documentatie van uw provider voor meer informatie.
Beperkingen
- MigrateAsync Verpakken in een expliciete transactie wordt niet ondersteund. Zie Uitzondering wordt gegenereerd bij het toepassen van migraties in een expliciete transactie voor meer informatie.
- Op SQLite kunnen verlaten migratievergrendelingen volgende migraties blokkeren.