Správa migrací

Při změnách modelu se migrace přidají a odeberou jako součást normálního vývoje a soubory migrace se kontrolují do správy zdrojového kódu projektu. Pokud chcete spravovat migrace, musíte nejdřív nainstalovat nástroje příkazového řádku EF Core.

Tip

Pokud je objekt DbContext v jiném sestavení než spouštěný projekt, můžete explicitně určit cílové a spouštěné projekty v nástrojích konzoly Správce balíčků nebo v nástrojích rozhraní příkazového řádku .NET Core.

Přidání migrace

Po změně modelu můžete přidat migraci pro tuto změnu:

dotnet ef migrations add AddBlogCreatedTimestamp

Název migrace se dá použít jako zpráva potvrzení v systému správy verzí. Můžete například zvolit název, například AddBlogCreatedTimestamp , pokud je změna nová CreatedTimestamp vlastnost entity Blog .

Do projektu se v adresáři Migrace přidají tři soubory:

  • XXXXXXXXXXXXXX_AddCreatedTimestamp.cs--Hlavní soubor migrace. Obsahuje operace potřebné k použití migrace (v Up) a vrácení (v Down).
  • XXXXXXXXXXXXXX_AddCreatedTimestamp.Designer.cs--- Soubor metadat migrace. Obsahuje informace používané ef.
  • MyContextModelSnapshot.cs--A snímek aktuálního modelu. Používá se k určení toho, co se změnilo při přidání další migrace.

Časové razítko v názvu souboru pomáhá udržovat je seřazené chronologicky, abyste viděli průběh změn.

Obory názvů

Soubory migrace můžete přesunout a změnit jejich obor názvů ručně. Nové migrace se vytvářejí na stejné úrovni jako na stejné úrovni poslední migrace. Případně můžete adresář zadat v době generování následujícím způsobem:

dotnet ef migrations add InitialCreate --output-dir Your/Directory

Poznámka

Obor názvů můžete změnit také nezávisle na adresáři pomocí --namespace.

Přizpůsobení kódu migrace

I když EF Core obecně vytváří přesné migrace, měli byste vždy zkontrolovat kód a ujistit se, že odpovídá požadované změně; v některých případech je to dokonce nutné.

Přejmenování sloupců

Jedním z případných příkladů, kdy je při přejmenování vlastnosti vyžadováno přizpůsobení migrací. Pokud například přejmenujete vlastnost z Name na FullName, EF Core vygeneruje následující migraci:

migrationBuilder.DropColumn(
    name: "Name",
    table: "Customers");

migrationBuilder.AddColumn<string>(
    name: "FullName",
    table: "Customers",
    nullable: true);

EF Core obecně nedokáže zjistit, kdy má záměr vložit sloupec a vytvořit nový (dva samostatné změny) a kdy se má sloupec přejmenovat. Pokud se výše uvedená migrace použije tak, jak je, ztratí se všechna vaše jména zákazníků. Pokud chcete přejmenovat sloupec, nahraďte výše vygenerovanou migraci následujícím kódem:

migrationBuilder.RenameColumn(
    name: "Name",
    table: "Customers",
    newName: "FullName");

Tip

Proces generování uživatelského rozhraní migrace upozorní, když operace může vést ke ztrátě dat (například vyřazení sloupce). Pokud se vám zobrazí toto upozornění, nezapomeňte si projít kód migrace s ohledem na přesnost.

Přidání nezpracovaných SQL

Při přejmenování sloupce je možné dosáhnout prostřednictvím integrovaného rozhraní API, v mnoha případech to není možné. Můžeme například chtít nahradit existující FirstName a LastName vlastnosti jedinou novou FullName vlastností. Migrace generovaná ef Core bude následující:

migrationBuilder.DropColumn(
    name: "FirstName",
    table: "Customer");

migrationBuilder.DropColumn(
    name: "LastName",
    table: "Customer");

migrationBuilder.AddColumn<string>(
    name: "FullName",
    table: "Customer",
    nullable: true);

Stejně jako předtím by to způsobilo nežádoucí ztrátu dat. Pokud chcete přenést data ze starých sloupců, přeuspořádáme migrace a provedeme nezpracovanou operaci SQL následujícím způsobem:

migrationBuilder.AddColumn<string>(
    name: "FullName",
    table: "Customer",
    nullable: true);

migrationBuilder.Sql(
@"
    UPDATE Customer
    SET FullName = FirstName + ' ' + LastName;
");

migrationBuilder.DropColumn(
    name: "FirstName",
    table: "Customer");

migrationBuilder.DropColumn(
    name: "LastName",
    table: "Customer");

Libovolné změny prostřednictvím nezpracovaného SQL

Nezpracovaný SQL lze také použít ke správě databázových objektů, o které EF Core neví. Chcete-li to provést, přidejte migraci bez provedení jakékoli změny modelu; Vygeneruje se prázdná migrace, kterou pak můžete naplnit nezpracovanými operacemi SQL.

Například následující migrace vytvoří uloženou proceduru SQL Serveru:

migrationBuilder.Sql(
@"
    EXEC ('CREATE PROCEDURE getFullName
        @LastName nvarchar(50),
        @FirstName nvarchar(50)
    AS
        RETURN @LastName + @FirstName;')");

Tip

EXEC se používá, když příkaz musí být první nebo pouze jeden v dávce SQL. Dá se také použít k řešení chyb analyzátoru ve skriptech idempotentní migrace, ke kterým může dojít, když odkazované sloupce v tabulce aktuálně neexistují.

Můžete ho použít ke správě libovolného aspektu databáze, včetně těchto:

  • Uložené procedury
  • Fulltextové vyhledávání
  • Funkce
  • Aktivační události
  • Zobrazení

Ve většině případů EF Core při použití migrací automaticky zabalí každou migraci do své vlastní transakce. Některé operace migrace bohužel nelze provést v rámci transakce v některých databázích; v těchto případech se můžete odhlásit z transakce předáním suppressTransaction: truemigrationBuilder.Sql.

Odebrání migrace

Někdy přidáte migraci a zjistíte, že před použitím je potřeba provést další změny modelu EF Core. Pokud chcete poslední migraci odebrat, použijte tento příkaz.

dotnet ef migrations remove

Po odebrání migrace můžete provést další změny modelu a znovu ho přidat.

Upozorňující

Vyhněte se odebrání migrací, které už byly použity pro produkční databáze. To znamená, že nebudete moct tyto migrace z databází vrátit a můžete narušit předpoklady provedené následnými migracemi.

Výpis migrací

Všechny existující migrace můžete zobrazit následujícím způsobem:

dotnet ef migrations list

Kontrola čekajících změn modelu

Poznámka

Tato funkce byla přidána v EF Core 8.0.

Někdy můžete chtít zkontrolovat, jestli nedošlo k nějakým změnám modelu od poslední migrace. To vám může pomoct zjistit, kdy jste vy nebo člen týmu zapomněli přidat migraci. Jedním ze způsobů, jak to udělat, je použít tento příkaz.

dotnet ef migrations has-pending-model-changes

Tuto kontrolu můžete provést také prostřednictvím kódu programu.context.Database.HasPendingModelChanges() To se dá použít k zápisu testu jednotek, který selže, když zapomenete přidat migraci.

Resetování všech migrací

V některých extrémních případech může být nutné odebrat všechny migrace a začít znovu. To můžete snadno provést odstraněním složky Migrace a vyřazením databáze. V tomto okamžiku můžete vytvořit novou počáteční migraci, která bude obsahovat celé vaše aktuální schéma.

Je také možné resetovat všechny migrace a vytvořit jednu migraci bez ztráty dat. To se někdy nazývá "squashing" a zahrnuje některé ruční práce:

  1. Zálohujte databázi, v případě, že se něco nepovede.
  2. V databázi odstraňte všechny řádky z tabulky historie migrací (např. DELETE FROM [__EFMigrationsHistory] na SQL Serveru).
  3. Odstraňte složku Migrations .
  4. Vytvořte novou migraci a vygenerujte pro ni skript SQL (dotnet ef migrations script).
  5. Vložte do historie migrací jeden řádek a poznamenejte si, že se už použila první migrace, protože vaše tabulky už existují. Insert SQL je poslední operace ve skriptu SQL vygenerovaném výše a podobá se následující (nezapomeňte aktualizovat hodnoty):
INSERT INTO [__EFMigrationsHistory] ([MIGRATIONID], [PRODUCTVERSION])
VALUES (N'<full_migration_timestamp_and_name>', N'<EF_version>');

Upozorňující

Při odstranění složky Migrations dojde ke ztrátě jakéhokoli vlastního kódu migrace. Všechna vlastní nastavení se musí na novou počáteční migraci použít ručně, aby se zachovala.

Další prostředky