Cvičení – nastavení migrace

Dokončeno

V této lekci vytvoříte třídy entit jazyka C#, které se mapují na tabulky v místní databázi SQLite. Funkce migrace EF Core vytváří tabulky z těchto entit.

Migrace poskytuje způsob přírůstkové aktualizace schématu databáze.

Získání souborů projektu

Začněte tím, že získáte soubory projektu. Máte několik možností, jak získat soubory projektu:

  • Použití GitHub Codespaces
  • Klonování úložiště GitHub

Pokud máte nainstalovaný kompatibilní modul runtime kontejneru, můžete také pomocí rozšíření Dev Containers otevřít úložiště v kontejneru s předinstalovanými nástroji.

Použití GitHub Codespaces

Codespace je integrované vývojové prostředí (IDE) hostované v cloudu. Pokud používáte GitHub Codespaces, přejděte do úložiště v prohlížeči. Vyberte Kód a pak ve větvi vytvořte nový prostor main kódu.

Klonování úložiště GitHub

Pokud nepoužíváte GitHub Codespaces, můžete naklonovat úložiště GitHubu projektu a pak soubory otevřít jako složku v editoru Visual Studio Code.

  1. Otevřete příkazový terminál a potom naklonujte projekt z GitHubu pomocí příkazového řádku:

    git clone https://github.com/MicrosoftDocs/mslearn-persist-data-ef-core
    
  2. Přejděte do složky mslearn-persist-data-ef-core a otevřete projekt v editoru Visual Studio Code:

    cd mslearn-persist-data-ef-core
    code .
    

Kontrola kódu

Teď, když máte soubory projektu, se kterými můžete pracovat, se podívejme, co je v projektu, a podívejme se na kód.

  • Projekt webového rozhraní API ASP.NET Core se nachází v adresáři ContosoPizza . Cesty k souborům, na které odkazujeme v tomto modulu, jsou relativní vzhledem k adresáři ContosoPizza .
  • Služby/PizzaService.cs je třída služby, která definuje metody vytvoření, čtení, aktualizace a odstranění (CRUD). Všechny metody v současné době vyvolat System.NotImplementedException.
  • V Program.csPizzaService je zaregistrovaný v systému injektáže závislostí ASP.NET Core.
  • Kontrolery/PizzaController.cs je hodnota, ApiController která zveřejňuje koncový bod pro příkazy HTTP POST, GET, PUT a DELETE. Tyto příkazy volají odpovídající metody CRUD pro PizzaService. PizzaService se vloží do konstruktoru PizzaController .
  • Složka Models obsahuje modely, které PizzaService a PizzaController používají.
  • Modely entit, Pizza.cs, Topping.cs a Sauce.cs, mají následující relace:
    • Pizza může mít jednu nebo více zastavování.
    • Zastavování lze použít na jedné nebo na mnoha pizzách.
    • Pizza může mít jednu omáčku, ale omáčku lze použít na mnoha pizzách.

Vytvoření aplikace

Sestavení aplikace v editoru Visual Studio Code:

  1. V podokně Průzkumník klikněte pravým tlačítkem na adresář ContosoPizza a vyberte Otevřít v integrovaném terminálu.

    Otevře se podokno terminálu s oborem adresáře ContosoPizza .

  2. Sestavte aplikaci pomocí následujícího příkazu:

    dotnet build
    

    Kód by se měl sestavit bez upozornění nebo chyb.

Přidání balíčků NuGet a nástrojů EF Core

Databázový stroj, se kterým pracujete v tomto modulu, je SQLite. SQLite je jednoduchý databázový stroj založený na souborech. Je to dobrá volba pro vývoj a testování a je také dobrou volbou pro malá produkční nasazení.

Poznámka:

Jak už bylo zmíněno dříve, zprostředkovatelé databází v EF Core jsou připojitelné. SQLite je pro tento modul dobrou volbou, protože je odlehčený a multiplatformní. Stejný kód můžete použít pro práci s různými databázovými stroji, jako je SQL Server a PostgreSQL. Ve stejné aplikaci můžete dokonce použít více databázových strojů.

Než začnete, přidejte požadované balíčky:

  1. V podokně terminálu spusťte následující příkaz:

    dotnet add package Microsoft.EntityFrameworkCore.Sqlite
    

    Tento příkaz přidá balíček NuGet, který obsahuje zprostředkovatele databáze EF Core SQLite a všechny jeho závislosti, včetně běžných služeb EF Core.

  2. Potom spusťte tento příkaz:

    dotnet add package Microsoft.EntityFrameworkCore.Design
    

    Tento příkaz přidá balíčky potřebné pro nástroje EF Core.

  3. Dokončení dokončíte spuštěním tohoto příkazu:

    dotnet tool install --global dotnet-ef
    

    Tento příkaz nainstaluje dotnet efnástroj, který používáte k vytváření migrací a generování uživatelského rozhraní.

    Tip

    Pokud dotnet ef už je nainstalovaný, můžete ho aktualizovat spuštěním dotnet tool update --global dotnet-efpříkazu .

Modely generování uživatelského rozhraní a DbContext

Teď přidáte a nakonfigurujete implementaci DbContext . DbContext je brána, prostřednictvím které můžete pracovat s databází.

  1. Klikněte pravým tlačítkem na adresář ContosoPizza a přidejte novou složku s názvem Data.

  2. Ve složce Data vytvořte nový soubor s názvem PizzaContext.cs. Do prázdného souboru přidejte následující kód:

    using Microsoft.EntityFrameworkCore;
    using ContosoPizza.Models;
    
    namespace ContosoPizza.Data;
    
    public class PizzaContext : DbContext
    {
        public PizzaContext (DbContextOptions<PizzaContext> options)
            : base(options)
        {
        }
    
        public DbSet<Pizza> Pizzas => Set<Pizza>();
        public DbSet<Topping> Toppings => Set<Topping>();
        public DbSet<Sauce> Sauces => Set<Sauce>();
    }
    

    V předchozím kódu:

    • Konstruktor přijímá parametr typu DbContextOptions<PizzaContext>. Konstruktor umožňuje externímu kódu předat konfiguraci, aby bylo možné totéž DbContext sdílet mezi testovacím a produkčním kódem a dokonce i s různými poskytovateli.
    • Vlastnosti DbSet<T> odpovídají tabulkám, které se mají vytvořit v databázi.
    • Názvy tabulek odpovídají názvům DbSet<T> vlastností ve PizzaContext třídě. Toto chování můžete v případě potřeby přepsat.
    • Při vytváření PizzaContext instance zpřístupňuje Pizzasobjekty , Toppingsa Sauces vlastnosti. Změny provedené v kolekcích, které zpřístupňují tyto vlastnosti, se rozšíří do databáze.
  3. V Program.cs nahraďte // Add the PizzaContext následujícím kódem:

    builder.Services.AddSqlite<PizzaContext>("Data Source=ContosoPizza.db");
    

    Předchozí kód:

    • Zaregistruje PizzaContext se v systému injektáže závislostí ASP.NET Core.
    • Určuje, že PizzaContext používá zprostředkovatele databáze SQLite.
    • Definuje připojovací řetězec SQLite, který odkazuje na místní soubor ContosoPizza.db.

    Poznámka:

    SQLite používá místní databázové soubory, takže je v pořádku pevně zakódovat připojovací řetězec. U síťových databází, jako je PostgreSQL a SQL Server, byste měli vždy bezpečně ukládat svoje připojovací řetězec. Pro místní vývoj použijte Secret Manager. Pro produkční nasazení zvažte použití služby, jako je Azure Key Vault.

  4. V Program.cs nahraďte // Additional using declarations následujícím kódem.

    using ContosoPizza.Data;
    

    Tento kód vyřeší závislosti v předchozím kroku.

  5. Uložte všechny provedené změny. GitHub Codespaces ukládá vaše změny automaticky.

  6. Sestavte aplikaci v terminálu spuštěním dotnet buildpříkazu . Sestavení by mělo být úspěšné bez upozornění nebo chyb.

Vytvoření a spuštění migrace

Dále vytvořte migraci, kterou můžete použít k vytvoření počáteční databáze.

  1. V terminálu vymezeném do složky projektu ContosoPizza spusťte následující příkaz, který vygeneruje migraci pro vytváření databázových tabulek:

    dotnet ef migrations add InitialCreate --context PizzaContext
    

    V předcházejícím příkazu:

    • Migrace má název: InitialCreate.
    • Možnost --context určuje název třídy v projektu ContosoPizza, která je odvozená z třídy DbContext.

    Nový adresář Migrations se zobrazí v kořenovém adresáři projektu ContosoPizza. Tento adresář obsahuje <timestamp>_InitialCreate.cs soubor, který popisuje změny databáze, které se mají přeložit do skriptu změny DDL (Data Definition Language).

  2. Spuštěním následujícího příkazu použijte migraci InitialCreate:

    dotnet ef database update --context PizzaContext
    

    Tento příkaz použije migraci. ContosoPizza.db neexistuje, takže tento příkaz vytvoří migraci v adresáři projektu.

    Tip

    Nástroj podporují dotnet ef všechny platformy. V sadě Visual Studio ve Windows můžete použít Add-Migration rutiny PowerShellu Update-Database v integrovaném okně konzoly Správce balíčků.

Kontrola databáze

EF Core vytvořila databázi pro vaši aplikaci. V dalším kroku se podíváme do databáze pomocí rozšíření SQLite.

  1. V podokně Průzkumník klikněte pravým tlačítkem na soubor ContosoPizza.db a vyberte Otevřít databázi.

    Snímek obrazovky znázorňující možnost nabídky Otevřít databázi v podokně Průzkumník editoru Visual Studio Code

    V podokně Průzkumník se zobrazí složka SQLite Explorer.

    Snímek obrazovky znázorňující složku Průzkumníka SQLite v podokně Průzkumník

  2. Vyberte složku PrůzkumníkA SQLite a rozbalte uzel a všechny jeho podřízené uzly. Klikněte pravým tlačítkem na ContosoPizza.db a výběrem možnosti Zobrazit tabulku sqlite_master zobrazte úplné schéma databáze a omezení, která migrace vytvořila.

    Snímek obrazovky znázorňující rozbalenou složku Průzkumníka SQLite v podokně Průzkumník

    • Tabulky, které odpovídají každé entitě, byly vytvořeny.
    • Názvy tabulek byly převzaty z názvů DbSet vlastností v objektu PizzaContext.
    • Pojmenované Id vlastnosti byly odvozeny tak, aby automaticky navyšovaly pole primárního klíče.
    • Zásady vytváření názvů omezení primárního klíče EF Core a cizího klíče jsou PK_<primary key property> a FK_<dependent entity>_<principal entity>_<foreign key property>v uvedeném pořadí. Zástupné symboly <dependent entity> a <principal entity> odpovídají názvům tříd entit.

    Poznámka:

    Stejně jako ASP.NET Core MVC používá EF Core konvenci oproti přístupu ke konfiguraci . Konvence EF Core zkracují dobu vývoje tím, že usuzují na záměr vývojáře. Ef Core například odvodí vlastnost s názvem Id nebo <entity name>Id jako primární klíč vygenerované tabulky. Pokud se rozhodnete neschválit konvenci vytváření názvů, musíte vlastnost anotovat pomocí atributu [Key] nebo ji nakonfigurovat jako klíč v OnModelCreating metodě DbContext.

Změna modelu a aktualizace schématu databáze

Váš nadřízený ve společnosti Contoso Pizza poskytuje některé nové požadavky, takže musíte změnit modely entit. V následujících krocích upravíte modely pomocí atributů mapování (někdy označovaných jako datové poznámky).

  1. V modelech\Pizza.cs proveďte následující změny:

    1. Přidat direktivu using pro System.ComponentModel.DataAnnotations.
    2. [Required] Přidejte atribut před Name vlastnost, aby se vlastnost označila jako povinná.
    3. [MaxLength(100)] Před vlastnost přidejte atributName, který určuje maximální délku řetězce 100.

    Aktualizovaný soubor Pizza.cs by měl vypadat jako následující kód:

    using System.ComponentModel.DataAnnotations;
    
    namespace ContosoPizza.Models;
    
    public class Pizza
    {
        public int Id { get; set; }
    
        [Required]
        [MaxLength(100)]
        public string? Name { get; set; }
    
        public Sauce? Sauce { get; set; }
    
        public ICollection<Topping>? Toppings { get; set; }
    }
    
  2. V modelech\Sauce.cs proveďte následující změny:

    1. Přidat direktivu using pro System.ComponentModel.DataAnnotations.
    2. [Required] Přidejte atribut před Name vlastnost, aby se vlastnost označila jako povinná.
    3. [MaxLength(100)] Před vlastnost přidejte atributName, který určuje maximální délku řetězce 100.
    4. bool Přidejte vlastnost s názvem IsVegan.

    Aktualizovaný soubor Sauce.cs by měl vypadat jako následující kód:

    using System.ComponentModel.DataAnnotations;
    
    namespace ContosoPizza.Models;
    
    public class Sauce
    {
        public int Id { get; set; }
    
        [Required]
        [MaxLength(100)]
        public string? Name { get; set; }
    
        public bool IsVegan { get; set; }
    }
    
  3. V modelech\Topping.cs proveďte následující změny:

    1. Přidat using direktivy pro System.ComponentModel.DataAnnotations a System.Text.Json.Serialization.

    2. [Required] Přidejte atribut před Name vlastnost, aby se vlastnost označila jako povinná.

    3. [MaxLength(100)] Před vlastnost přidejte atributName, který určuje maximální délku řetězce 100.

    4. Přidejte vlastnost pojmenovanou decimal Calories bezprostředně za Name vlastností.

    5. Pizzas Přidat vlastnost typu ICollection<Pizza>?. Tato změna provede Pizza-Topping relaci M:N.

    6. [JsonIgnore] Přidejte do Pizzas vlastnosti atribut.

      Důležité

      Tento atribut zabraňuje Topping entitám v zahrnutí Pizzas vlastnosti, když kód webového rozhraní API serializuje odpověď na JSON. Bez této změny by serializovaná kolekce zastavování zahrnovala kolekci každé pizzy, která používá zastavení. Každá pizza v této kolekci by obsahovala kolekci zastavování, která by každá z nich opět obsahovala kolekci pizz. Tento typ nekonečné smyčky se nazývá cyklický odkaz a nelze jej serializovat.

    Aktualizovaný soubor Topping.cs by měl vypadat jako následující kód:

    using System.ComponentModel.DataAnnotations;
    using System.Text.Json.Serialization;
    
    namespace ContosoPizza.Models;
    
    public class Topping
    {
        public int Id { get; set; }
    
        [Required]
        [MaxLength(100)]
        public string? Name { get; set; }
    
        public decimal Calories { get; set; }
    
        [JsonIgnore]
        public ICollection<Pizza>? Pizzas { get; set; }
    }
    
  4. Uložte všechny provedené změny a spusťte dotnet build.

  5. Spuštěním následujícího příkazu vygenerujte migraci pro vytvoření databázových tabulek:

    dotnet ef migrations add ModelRevisions --context PizzaContext
    

    Tento příkaz vytvoří migraci s názvem: ModelRevisions.

    Poznámka:

    Zobrazí se tato zpráva: Vygenerovala se operace, která může vést ke ztrátě dat. Zkontrolujte přesnost migrace. Tato zpráva se objevila, protože jste změnili relaci z Pizza 1:N na Topping M:N, což vyžaduje vyřazení existujícího sloupce cizího klíče. Vzhledem k tomu, že ještě ve své databázi nemáte žádná data, tato změna není problematická. Obecně je ale vhodné zkontrolovat vygenerovanou migraci, když se zobrazí toto upozornění, abyste měli jistotu, že migrace neodstraní nebo nezkrátí žádná data.

  6. Spuštěním následujícího příkazu použijte migraci ModelRevisions:

    dotnet ef database update --context PizzaContext
    
  7. Na záhlaví složky PrůzkumníkA SQLite vyberte tlačítko Aktualizovat databáze .

    Snímek obrazovky znázorňující tlačítko Aktualizovat databáze v záhlaví Průzkumníka SQLite

  8. Ve složce SQLite Explorer klikněte pravým tlačítkem na ContosoPizza.db. Výběrem možnosti Zobrazit tabulku sqlite_master zobrazte úplné schéma a omezení databáze.

    Důležité

    Rozšíření SQLite znovu používá otevřené karty SQLite .

    • Vytvořili PizzaTopping jsme tabulku spojení, která představuje relaci M:N mezi pizzami a zastavovacími sadou.
    • Nová pole byla přidána do Toppings a Sauces.
      • Calories je definován jako sloupec, text protože SQLite nemá odpovídající decimal typ.
      • IsVegan Podobně je definován jako integer sloupec. SQLite nedefinuje bool typ.
      • V oboupřípadechch
    • Sloupec Name v každé tabulce byl označen not null, ale SQLite nemá MaxLength omezení.

    Tip

    Poskytovatelé databází EF Core mapuje schéma modelu na funkce konkrétní databáze. I když SQLite neimplementuje odpovídající omezení pro MaxLengthostatní databáze, jako je SQL Server a PostgreSQL.

  9. Ve složce PrůzkumníkA SQLite klikněte pravým tlačítkem myši na _EFMigrationsHistory tabulku a vyberte Zobrazit tabulku. Tabulka obsahuje seznam všech migrací použitých pro databázi. Vzhledem k tomu, že jste spustili dvě migrace, existují dvě položky: jednu pro migraci InitialCreate a druhou pro ModelRevisions.

Poznámka:

V tomto cvičení se k mapování modelů na databázi použily atributy mapování (datové poznámky). Jako alternativu k mapování atributů můžete ke konfiguraci modelů použít rozhraní API fluent ModelBuilder. Oba přístupy jsou platné, ale někteří vývojáři dávají přednost jednomu přístupu před druhým.

Migrace jste použili k definování a aktualizaci schématu databáze. V další lekci dokončíte metody, které PizzaService manipulují s daty.

Kontrola znalostí

1.

Jaká je konvence tvorby názvů pro primární klíč ve třídě entity?