Cvičení – nastavení migrace

Dokončeno

V této lekci vytvoříte třídy entit jazyka C#, které se budou mapovat 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í hostované v cloudu. Pokud používáte GitHub Codespaces, přejděte v prohlížeči do úložiště. Vyberte Code (Kód) a pak ve main větvi vytvořte nový codespace.

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

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

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

    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ď máte soubory projektu, se kterými můžete pracovat. Podívejte se, co je v projektu, a zkontrolujte kód.

  • Projekt, ASP.NET Core webové rozhraní API, se nachází v adresáři ContosoPizza. Cesty k souborům, na které se odkazuje v tomto modulu, jsou relativní vzhledem k adresáři ContosoPizza .
  • Services/PizzaService.cs je třída služby, která definuje metody CRUD (create, read, update a delete). Všechny metody v současné době volají System.NotImplementedException.
  • V souboru Program.csPizzaService je zaregistrovaný v systému ASP.NET Core injektáž závislostí.
  • Controllers/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 na PizzaService. PizzaService se vloží do konstruktoru PizzaController .
  • Složka Models obsahuje modely, které jsou používány PizzaService a PizzaController.
  • Modely entit Pizza.cs, Topping.cs a Sauce.cs mají následující relace:
    • Pizza může mít jednu nebo více pochvy.
    • Polevou lze použít na jednu pizzu nebo na mnoho pizz.
    • Pizza může mít jednu omáčku, ale omáčku lze použít na mnoho pizz.

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 nastaveným na adresář 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 v tomto modulu pracujete, je SQLite. SQLite je jednoduchý databázový stroj založený na souborech. Je to dobrá volba pro vývoj a testování a také pro nasazení v malém měřítku v produkčním prostředí.

Poznámka

Jak už bylo zmíněno dříve, poskytovatelé databází v EF Core jsou připojitelné. SQLite je dobrou volbou pro tento modul, protože je jednoduchý a multiplatformní. Stejný kód můžete použít pro práci s různými databázovými stroji, jako jsou 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. Spusťte tento příkaz:

    dotnet add package Microsoft.EntityFrameworkCore.Design
    

    Tento příkaz přidá balíčky, které jsou potřeba pro nástroje EF Core.

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

    dotnet tool install --global dotnet-ef
    

    Tento příkaz nainstaluje dotnet efnástroj , který použijete 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 příkazu dotnet tool update --global dotnet-ef.

Generování modelů a DbContext

Teď přidáte a nakonfigurujete implementaci DbContext . DbContext je brána, přes kterou 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 tak, aby se stejná DbContext možnost sdílela mezi testovacím a produkčním kódem a dokonce byla použita s různými zprostředkovateli.
    • Vlastnosti DbSet<T> odpovídají tabulkám, které se mají vytvořit v databázi.
    • Názvy tabulek budou odpovídat názvům vlastností DbSet<T> ve třídě PizzaContext. V případě potřeby můžete toto chování přepsat.
    • Při vytvoření PizzaContext instance nástroj zpřístupní Pizzasvlastnosti , Toppingsa Sauces . Změny, které provedete v kolekcích vystavených těmito vlastnostmi, se rozšíří do databáze.
  3. V souboru 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:

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

    Poznámka

    SQLite používá soubory místní databáze, takže je pravděpodobně 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 připojovací řetězce vždy bezpečně ukládat. Pro místní vývoj použijte Secret Manager. V případě produkčních nasazení zvažte použití služby, jako je Azure Key Vault.

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

    using ContosoPizza.Data;
    

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

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

  6. Sestavte aplikaci v terminálu spuštěním příkazu dotnet build. Sestavení by mělo proběhnout ú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. Spuštěním následujícího příkazu vygenerujte migraci pro vytvoření databázových tabulek:

    dotnet ef migrations add InitialCreate --context PizzaContext
    

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

    • Migrace dostane 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. Adresář obsahuje <timestamp>_InitialCreate.cs soubor, který popisuje změny databáze, které se mají přeložit do změnového skriptu jazyka 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 migrace se vytvoří v adresáři projektu.

    Tip

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

Kontrola databáze

EF Core vytvořil pro vaši aplikaci databázi. Dále se pomocí rozšíření SQLite podívejte do databáze.

  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 s možností nabídky Otevřít databázi v podokně Průzkumníka editoru Visual Studio Code

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

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

  2. Výběrem složky SQLite Explorer rozbalte uzel a všechny jeho podřízené uzly. Klikněte pravým tlačítkem na ContosoPizza.db a vyberte Zobrazit tabulku sqlite_master . Zobrazí se úplné schéma databáze a omezení, které migrace vytvořila.

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

    • Byly vytvořeny tabulky, které odpovídají jednotlivým entitám.
    • Názvy tabulek byly převzaty z názvů DbSet vlastností v objektu PizzaContext.
    • Vlastnosti s názvem Id byly odvozeny tak, aby automaticky zvýšovaly pole primárního klíče.
    • Konvence primárního klíče EF Core a omezení cizího klíče jsou PK_<primary key property> a FK_<dependent entity>_<principal entity>_<foreign key property>. Zástupné symboly <dependent entity> a <principal entity> odpovídají názvům tříd entit.

    Poznámka

    Stejně jako ASP.NET Core MVC i EF Core používá konvenci přístupu ke konfiguraci. Konvence EF Core zkracují dobu vývoje tím, že usuzují na záměr vývojáře. Například vlastnost s názvem Id nebo <entity name>Id se posoudí tak, že to má být vygenerovaný primární klíč tabulky. Pokud se rozhodnete nepřijmout konvenci vytváření názvů, musí být vlastnost označena atributem [Key] nebo nakonfigurována jako klíč v OnModelCreating metodě DbContext.

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

Váš nadřízený ve společnosti Contoso Pizza vám dává několik nových požadavků, 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 souboru Models\Pizza.cs proveďte následující změny:

    1. Přidejte direktivu using pro System.ComponentModel.DataAnnotations.
    2. [Required] Přidejte atribut před Name vlastnost a označte vlastnost jako požadovanou.
    3. [MaxLength(100)] Přidejte atribut před Name vlastnost a určete maximální délku řetězce 100.
    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 souboru Models\Sauce.cs proveďte následující změny:

    1. Přidejte direktivu using pro System.ComponentModel.DataAnnotations.
    2. [Required] Přidejte atribut před Name vlastnost a označte vlastnost jako požadovanou.
    3. [MaxLength(100)] Přidejte atribut před Name vlastnost a určete maximální délku řetězce 100.
    4. bool Přidejte vlastnost s názvem IsVegan.
    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 souboru Models\Topping.cs proveďte následující změny:

    1. Přidejte using direktivy pro System.ComponentModel.DataAnnotations a System.Text.Json.Serialization.
    2. [Required] Přidejte atribut před Name vlastnost a označte vlastnost jako požadovanou.
    3. [MaxLength(100)] Přidejte atribut před Name vlastnost a určete maximální délku řetězce 100.
    4. decimal Přidejte vlastnost s názvem Calories hned za vlastnostName.
    5. Pizzas Přidejte vlastnost typu ICollection<Pizza>? pro vytvoření Pizza-Topping relace M:N.
    6. [JsonIgnore] Přidejte do Pizzas vlastnosti atribut.

    Důležité

    Tyto kroky zabrání Topping entitám Pizzas v zahrnutí vlastnosti, když kód webového rozhraní API serializuje odpověď na JSON. Bez této změny by serializovaná kolekce poleva zahrnovala kolekci každé pizzy, která používá poleva. Každá pizza v této kolekci bude obsahovat kolekci poleva, z nichž každá bude opět obsahovat kolekci pizz. Tento typ nekonečné smyčky se nazývá cyklický odkaz a nedá se serializovat.

    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 změny a spusťte dotnet buildpříkaz .

  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
    

    Vytvoří se migrace s názvem ModelRevisions .

    Poznámka

    Zobrazí se tato zpráva: Byla vygenerována operace, která může vést ke ztrátě dat. Zkontrolujte přesnost migrace. Zpráva se zobrazí, protože jste změnili relaci z Pizza 1: Topping N na M:N, což vyžaduje vyřazení existujícího sloupce cizího klíče. Vzhledem k tomu, že v databázi ještě nemáte žádná data, není tato změna problematická. Obecně je ale vhodné zkontrolovat vygenerovanou migraci, když se zobrazí toto upozornění, abyste měli jistotu, že migrace nesmažou ani 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. V záhlaví složky SQLite Explorer vyberte tlačítko Aktualizovat databáze .

    Snímek obrazovky znázorňující tlačítko Aktualizovat databáze v záhlaví aplikace SQLite Explorer

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

    Důležité

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

    • Byla PizzaTopping vytvořena tabulka spojení, která představuje relaci M:N mezi pizzou a polevami.
    • Do a Saucesbyla přidána Toppings nová pole .
      • Calories je definovaný jako text sloupec, protože SQLite nemá odpovídající decimal typ.
      • Podobně IsVegan je definován jako integer sloupec. SQLite nedefinuje bool typ.
      • V obou případech spravuje překlad EF Core.
    • Sloupec Name v každé tabulce je označený not null, ale SQLite nemá MaxLength omezení.

    Tip

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

  9. Ve složce SQLite Explorer klikněte pravým tlačítkem myši na _EFMigrationsHistory tabulku a vyberte Zobrazit tabulku. Tabulka obsahuje seznam všech migrací, které se použijí na databázi. Vzhledem k tomu, že jste spustili dvě migrace, existují dvě položky: jedna pro migraci InitialCreate a druhá pro ModelRevisions.

Poznámka

Toto cvičení použilo atributy mapování (datové poznámky) k mapování modelů na databázi. Jako alternativu k atributům mapování 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.

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

Kontrola znalostí

1.

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