Použití migrací
Po přidání migrací je potřeba je nasadit a použít u databází. Existují různé strategie, kdy některé jsou vhodnější pro produkční prostředí a jiné pro životní cyklus vývoje.
Poznámka:
Bez ohledu na vaši strategii nasazení vždy zkontrolujte vygenerované migrace a před použitím na produkční databázi je otestujte. Migrace může odstranit sloupec, když byl záměr přejmenovat nebo může selhat z různých důvodů při použití databáze.
Skripty SQL
Doporučeným způsobem nasazení migrací do produkční databáze je generování skriptů SQL. Mezi výhody této strategie patří:
- Skripty SQL je možné zkontrolovat přesnost; to je důležité, protože použití změn schématu v produkčních databázích je potenciálně nebezpečná operace, která by mohla zahrnovat ztrátu dat.
- V některých případech je možné skripty ladit tak, aby vyhovovaly konkrétním potřebám produkční databáze.
- Skripty SQL je možné použít ve spojení s technologií nasazení a lze je dokonce vygenerovat v rámci procesu CI.
- Skripty SQL je možné poskytnout dbA a je možné je spravovat a archivovat samostatně.
Základní použití
Následující příkaz vygeneruje skript SQL z prázdné databáze na nejnovější migraci:
dotnet ef migrations script
With From (to implied)
Následující příkaz vygeneruje skript SQL z dané migrace na nejnovější migraci.
dotnet ef migrations script AddNewTables
With From and To
Následující příkaz vygeneruje skript SQL ze zadané from
migrace na zadanou to
migraci.
dotnet ef migrations script AddNewTables AddAuditTable
K vygenerování skriptu vrácení zpět můžete použít from
novější skript, který je novější než to
ten, který je novější.
Upozorňující
Poznamenejte si potenciální scénáře ztráty dat.
Generování skriptu přijímá následující dva argumenty, které označují, jaký rozsah migrací se má vygenerovat:
- Z migrace by měla být poslední migrace použitá na databázi před spuštěním skriptu. Pokud nebyly použity žádné migrace, zadejte
0
(toto je výchozí nastavení). - Migrace je poslední migrace, která se použije v databázi po spuštění skriptu. Výchozí hodnota je poslední migrace v projektu.
Idempotentní skripty SQL
Výše vygenerované skripty SQL je možné použít pouze ke změně schématu z jedné migrace na jinou; je vaší zodpovědností použít skript odpovídajícím způsobem a pouze na databáze ve správném stavu migrace. EF Core také podporuje generování idempotentních skriptů, které interně kontrolují, které migrace už byly použity (prostřednictvím tabulky historie migrací) a používají pouze chybějící. To je užitečné, pokud přesně nevíte, co byla poslední migrace použitá na databázi, nebo pokud nasazujete do více databází, které můžou být v jiné migraci.
Následující vygeneruje idempotentní migrace:
dotnet ef migrations script --idempotent
Nástroje příkazového řádku
Nástroje příkazového řádku EF je možné použít k použití migrací do databáze. I když je tato produktivita pro místní vývoj a testování migrací, tento přístup není ideální pro správu produkčních databází:
- Příkazy SQL se použijí přímo nástrojem, aniž by vývojáři dali možnost je zkontrolovat nebo upravit. To může být nebezpečné v produkčním prostředí.
- Sada .NET SDK a nástroj EF musí být nainstalovány na produkčních serverech a vyžaduje zdrojový kód projektu.
Poznámka:
Každá migrace se použije ve své vlastní transakci. Informace o možných budoucíchvylepšeních
Následující aktualizace databáze na nejnovější migraci:
dotnet ef database update
Následující aktualizace databáze na danou migraci:
dotnet ef database update AddNewTables
Mějte na paměti, že se dá použít i k vrácení na dřívější migraci.
Upozorňující
Poznamenejte si potenciální scénáře ztráty dat.
Další informace o použití migrací pomocí nástrojů příkazového řádku najdete v referenčních informacích k nástrojům EF Core.
Sady
Sady migrace jsou spustitelné soubory s jedním souborem, které je možné použít k použití migrací na databázi. Řeší některé nedostatky skriptu SQL a nástrojů příkazového řádku:
- Spouštění skriptů SQL vyžaduje další nástroje.
- Zpracování transakcí a chování těchto nástrojů při pokračování v chybě jsou nekonzistentní a někdy neočekávané. Pokud při použití migrací dojde k selhání, může databáze zůstat v nedefinovaném stavu.
- Balíčky je možné vygenerovat jako součást procesu CI a snadno je provést později v rámci procesu nasazení.
- Balíčky je možné spouštět bez instalace sady .NET SDK nebo nástroje EF (nebo dokonce i modulu runtime .NET, pokud jsou samostatné) a nevyžadují zdrojový kód projektu.
Následující vygeneruje sadu:
dotnet ef migrations bundle
Následující příkaz vygeneruje samostatnou sadu pro Linux:
dotnet ef migrations bundle --self-contained -r linux-x64
Další informace o vytváření sad najdete v referenčních informacích k nástrojům EF Core.
efbundle
Výsledný spustitelný soubor má ve výchozím nastavení název efbundle
. Dá se použít k aktualizaci databáze na nejnovější migraci. Je ekvivalentem spuštění dotnet ef database update
nebo Update-Database
.
Argumenty:
Argument | Popis |
---|---|
<MIGRATION> |
Cílová migrace. Pokud je 0, vrátí se všechny migrace. Výchozí hodnota je poslední migrace. |
Volby:
Možnost | Krátké | Popis |
---|---|---|
--connection <CONNECTION> |
Připojovací řetězec do databáze. Ve výchozím nastavení se nastaví hodnota zadaná v příkazu AddDbContext nebo OnConfiguring. | |
--verbose |
-v |
Zobrazení podrobného výstupu |
--no-color |
Nevybarvujte výstup. | |
--prefix-output |
Výstup předpony s úrovní |
Následující příklad používá migrace do místní instance SQL Serveru pomocí zadaného uživatelského jména a hesla.
.\efbundle.exe --connection 'Data Source=(local)\MSSQLSERVER;Initial Catalog=Blogging;User ID=myUsername;Password=myPassword'
Upozorňující
Nezapomeňte kopírovat appsettings.json společně se sadou. Sada spoléhá na přítomnost appsettings.json v adresáři spouštění.
Příklad migračního balíčku
Sada potřebuje migrace, které se mají zahrnout. Ty se vytvoří pomocí postupu dotnet ef migrations add
popsaného v tématu Vytvoření první migrace. Jakmile budete mít migrace připravené k nasazení, vytvořte sadu pomocí nástroje dotnet ef migrations bundle
. Příklad:
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>
Výstup je spustitelný soubor vhodný pro váš cílový operační systém. V mém případě to je Windows x64, takže se mi v efbundle.exe
místní složce zahodí. Spuštění tohoto spustitelného souboru použije migrace obsažené v něm:
PS C:\local\AllTogetherNow\SixOh> .\efbundle.exe
Applying migration '20210903083845_MyMigration'.
Done.
PS C:\local\AllTogetherNow\SixOh>
Stejně jako u dotnet ef database update
nebo Update-Database
se migrace použijí na databázi pouze v případě, že ještě nebyly použity. Například opětovné spuštění stejné sady nedělá nic, protože neexistují žádné nové migrace, které by se použily:
PS C:\local\AllTogetherNow\SixOh> .\efbundle.exe
No migrations were applied. The database is already up to date.
Done.
PS C:\local\AllTogetherNow\SixOh>
Pokud ale dojde ke změnám modelu a vygenerují dotnet ef migrations add
se další migrace, dají se sbalit do nového spustitelného souboru připraveného k použití. Příklad:
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
Možnost --force
lze použít k přepsání existující sady novou sadou.
Spuštěním této nové sady se na databázi použijí tyto dvě nové migrace:
PS C:\local\AllTogetherNow\SixOh> .\efbundle.exe
Applying migration '20210903084526_SecondMigration'.
Applying migration '20210903084538_Number3'.
Done.
PS C:\local\AllTogetherNow\SixOh>
Ve výchozím nastavení sada používá databázi připojovací řetězec z konfigurace vaší aplikace. Jinou databázi ale můžete migrovat předáním připojovací řetězec na příkazovém řádku. Příklad:
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>
Poznámka:
Tentokrát byly použity všechny tři migrace, protože žádná z nich ještě nebyla použita pro produkční databázi.
Použití migrací za běhu
Je možné, že samotná aplikace bude používat migrace prostřednictvím kódu programu, obvykle během spouštění. I když je tato produktivita pro místní vývoj a testování migrací, tento přístup není vhodný pro správu produkčních databází z následujících důvodů:
- U verzí EF před 9, pokud je spuštěno více instancí aplikace, by se obě aplikace mohly pokusit použít migraci souběžně a selhat (nebo horší, způsobit poškození dat).
- Podobně platí, že pokud aplikace přistupuje k databázi, zatímco ji migruje jiná aplikace, může to způsobit závažné problémy.
- Aby bylo možné změnit schéma databáze, musí mít aplikace přístup se zvýšenými oprávněními. Obecně je vhodné omezit oprávnění databáze aplikace v produkčním prostředí.
- V případě problému je důležité vrátit zpět použitou migraci. Další strategie poskytují tuto možnost snadno a mimo krabici.
- Příkazy SQL se použijí přímo programem, aniž by vývojáři dali možnost je zkontrolovat nebo upravit. To může být nebezpečné v produkčním prostředí.
Pokud chcete použít migrace prostřednictvím kódu programu, zavolejte context.Database.Migrate()
. Například typická aplikace ASP.NET může provádět následující akce:
public static void Main(string[] args)
{
var host = CreateHostBuilder(args).Build();
using (var scope = host.Services.CreateScope())
{
var db = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
db.Database.Migrate();
}
host.Run();
}
Mějte na paměti, že Migrate()
vychází ze IMigrator
služby, kterou je možné použít pro pokročilejší scénáře. Umožňuje myDbContext.GetInfrastructure().GetService<IMigrator>()
přístup k němu.
Upozorňující
- Před použitím tohoto přístupu v produkčním prostředí pečlivě zvažte. Zkušenosti ukázaly, že jednoduchost této strategie nasazení převáží problémy, které vytváří. Zvažte místo toho generování skriptů SQL z migrací.
- Nevolejte
EnsureCreated()
dřívMigrate()
.EnsureCreated()
projde migracemi pro vytvoření schématu, což způsobíMigrate()
selhání.