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.

Možnosti:

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 společně se sadou kopírovat soubor appsettings.json. Sada závisí na přítomnosti souboru 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-Databasese 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 addse 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ů:

  • Pokud je spuštěno více instancí aplikace, mohly by se obě aplikace 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řív Migrate(). EnsureCreated() projde migracemi pro vytvoření schématu, což způsobí Migrate() selhání.