Cvičení – přístup k datům ze komponenty Blazor

Dokončeno

Aktuální pevně zakódované pizzy v aplikaci je potřeba nahradit databází. Rozhraní Microsoft Entity Framework můžete použít k přidání připojení ke zdrojům dat. V této aplikaci použijeme databázi SQLite k ukládání pizz.

V tomto cvičení přidáte balíčky pro podporu funkcí databáze, připojíte třídy k back-endové databázi a přidáte pomocnou třídu pro předběžné načtení dat pro pizzy společnosti.

Přidání balíčků pro podporu přístupu k databázi

  1. Pokud je aplikace pořád spuštěná, zastavte ji.

  2. V editoru Visual Studio Code vyberte Terminal>New Terminal.

  3. V novém terminálu nastavte svou polohu na adresář BlazingPizza.

    cd BlazingPizza
    
  4. Spuštěním těchto příkazů přidejte microsoft.EntityFrameworkCore, balíčky Microsoft.EntityFrameworkCore.Sqlite a System.Net.Http.Json:

    dotnet add package Microsoft.EntityFrameworkCore --version 6.0.8
    dotnet add package Microsoft.EntityFrameworkCore.Sqlite --version 6.0.8
    dotnet add package System.Net.Http.Json --version 6.0.0
    

    Tyto příkazy přidávají odkazy na balíčky do souboru BlazingPizza.csproj:

      <ItemGroup>
        <PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.8" />
        <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="6.0.8" />
        <PackageReference Include="System.Net.Http.Json" Version="6.0.0" />
      </ItemGroup>
    

Přidání kontextu databáze

  1. V editoru Visual Studio Code vytvořte novou složku ve složce BlazingPizza. Pojmenujte ho data.

  2. Ve složce Data vytvořte nový soubor. Pojmenujte ho PizzaStoreContext.cs.

  3. Zadejte tento kód pro třídu:

    using Microsoft.EntityFrameworkCore;
    
    namespace BlazingPizza.Data;
    
    public class PizzaStoreContext : DbContext
    {
        public PizzaStoreContext(DbContextOptions options) : base(options)
        {
        }
    
        public DbSet<PizzaSpecial> Specials { get; set; }
    }    
    

    Tato třída vytvoří kontext databáze, který můžeme použít k registraci databázové služby. Kontext nám také umožňuje mít kontroler, který přistupuje k databázi.

  4. Uložte změny.

Přidání kontroleru

  1. Ve složce BlazingPizza vytvořte novou složku. Pojmenujte ho kontrolery.

  2. Ve složce Controllers vytvořte nový soubor. Pojmenujte ho SpecialsController.cs.

  3. Zadejte tento kód pro třídu:

    using Microsoft.AspNetCore.Mvc;
    using Microsoft.EntityFrameworkCore;
    using BlazingPizza.Data;
    
    namespace BlazingPizza.Controllers;
    
    [Route("specials")]
    [ApiController]
    public class SpecialsController : Controller
    {
        private readonly PizzaStoreContext _db;
    
        public SpecialsController(PizzaStoreContext db)
        {
            _db = db;
        }
    
        [HttpGet]
        public async Task<ActionResult<List<PizzaSpecial>>> GetSpecials()
        {
            return (await _db.Specials.ToListAsync()).OrderByDescending(s => s.BasePrice).ToList();
        }
    }
    

    Tato třída vytvoří řadič, který nám umožní vyhledávat v databázi speciality pizzy a vrátí je jako JSON na adrese URL (http://localhost:5000/specials).

  4. Uložte změny.

Načtení dat do databáze

Aplikace zkontroluje, jestli existuje existující databáze SQLite, a vytvoří ji s některými předem připravenými pizzami.

  1. V adresáři Data vytvořte nový soubor. Pojmenujte ho SeedData.cs.

  2. Zadejte tento kód pro třídu:

    namespace BlazingPizza.Data;
    
    public static class SeedData
    {
        public static void Initialize(PizzaStoreContext db)
        {
            var specials = new PizzaSpecial[]
            {
                new PizzaSpecial()
                {
                    Name = "Basic Cheese Pizza",
                    Description = "It's cheesy and delicious. Why wouldn't you want one?",
                    BasePrice = 9.99m,
                    ImageUrl = "img/pizzas/cheese.jpg",
                },
                new PizzaSpecial()
                {
                    Id = 2,
                    Name = "The Baconatorizor",
                    Description = "It has EVERY kind of bacon",
                    BasePrice = 11.99m,
                    ImageUrl = "img/pizzas/bacon.jpg",
                },
                new PizzaSpecial()
                {
                    Id = 3,
                    Name = "Classic pepperoni",
                    Description = "It's the pizza you grew up with, but Blazing hot!",
                    BasePrice = 10.50m,
                    ImageUrl = "img/pizzas/pepperoni.jpg",
                },
                new PizzaSpecial()
                {
                    Id = 4,
                    Name = "Buffalo chicken",
                    Description = "Spicy chicken, hot sauce and bleu cheese, guaranteed to warm you up",
                    BasePrice = 12.75m,
                    ImageUrl = "img/pizzas/meaty.jpg",
                },
                new PizzaSpecial()
                {
                    Id = 5,
                    Name = "Mushroom Lovers",
                    Description = "It has mushrooms. Isn't that obvious?",
                    BasePrice = 11.00m,
                    ImageUrl = "img/pizzas/mushroom.jpg",
                },
                new PizzaSpecial()
                {
                    Id = 7,
                    Name = "Veggie Delight",
                    Description = "It's like salad, but on a pizza",
                    BasePrice = 11.50m,
                    ImageUrl = "img/pizzas/salad.jpg",
                },
                new PizzaSpecial()
                {
                    Id = 8,
                    Name = "Margherita",
                    Description = "Traditional Italian pizza with tomatoes and basil",
                    BasePrice = 9.99m,
                    ImageUrl = "img/pizzas/margherita.jpg",
                },
            };
            db.Specials.AddRange(specials);
            db.SaveChanges();
        }
    }
    

    Třída používá předaný kontext databáze, vytvoří některé PizzaSpecial objekty v poli a pak je uloží.

  3. V Průzkumníku souborů vyberte Program.cs.

  4. Nahoře přidejte odkaz na nový PizzaStoreContext:

    using BlazingPizza.Data;
    

    Tento příkaz umožňuje aplikaci používat novou službu.

  5. Vložte tento segment nad metodu app.Run();:

    ...
    // Initialize the database
    var scopeFactory = app.Services.GetRequiredService<IServiceScopeFactory>();
    using (var scope = scopeFactory.CreateScope())
    {
        var db = scope.ServiceProvider.GetRequiredService<PizzaStoreContext>();
        if (db.Database.EnsureCreated())
        {
            SeedData.Initialize(db);
        }
    }
    
    app.Run();
    

    Tato změna vytvoří obor databáze s PizzaStoreContext. Pokud databáze ještě není vytvořená, zavolá SeedData statickou třídu a vytvoří ji.

  6. V tuto chvíli aplikace nefunguje, protože jsme neicializovali PizzaStoreContext. V Add Services to the container části výše v souboru Program.cs přidejte tento kód pod současnými službami (řádky, které začínají na builder.Services.):

      builder.Services.AddHttpClient();
      builder.Services.AddSqlite<PizzaStoreContext>("Data Source=pizza.db");
    
    

    Tento kód zaregistruje dvě služby. První příkaz AddHttpClient umožňuje aplikaci přístup k příkazům HTTP. Aplikace k získání kódu JSON pro speciality pizzy používá HttpClient. Druhý příkaz zaregistruje nový PizzaStoreContext a poskytne název souboru databáze SQLite.

Použití databáze k zobrazení pizz

Nyní můžeme nahradit pevně zakódovanou pizzu na stránce Index.razor.

  1. V Průzkumníku souborů vyberte Index.razor.

  2. Nahraďte existující metodu OnInitialized() tímto kódem:

    protected override async Task OnInitializedAsync()
    {
        specials = await HttpClient.GetFromJsonAsync<List<PizzaSpecial>>(NavigationManager.BaseUri + "specials");
    }
    

    Poznámka

    Tento kód nahradil OnInitialized()OnInitializedAsync(). Speciální položky se teď budou vracet jako JSON z aplikace asynchronně.

  3. Je potřeba opravit některé chyby. Do direktivy @page přidejte tyto příkazy @inject:

    @inject HttpClient HttpClient
    @inject NavigationManager NavigationManager
    
  4. Uložte všechny změny a pak vyberte F5 nebo vyberte Spustit. Pak vyberte Spustit ladění.

    Při spuštění aplikace dojde k chybě za běhu. JsonReader vyvolal výjimku.

  5. Mějte na paměti, že aplikace by měla vytvářet JSON na (http://localhost:5000/specials). Přejděte na adresu URL.

    Aplikace neví, jak tuto žádost směrovat. O směrování se dozvíte v modulu o směrování Blazor. Pojďme tuto chybu opravit.

  6. Vyberte Shift + F5, nebo vyberte Zastavit ladění.

  7. V Průzkumníku souborů vyberte Program.cs.

  8. Přibližně uprostřed souboru, po řádcích, které začínají app., přidejte tento koncový bod:

    app.MapControllerRoute("default", "{controller=Home}/{action=Index}/{id?}");
    

    Kód by teď měl být:

    ...
    app.MapRazorPages();
    app.MapBlazorHub();
    app.MapFallbackToPage("/_Host");
    app.MapControllerRoute("default", "{controller=Home}/{action=Index}/{id?}");
    ...
    
  9. Vyberte F5 nebo vyberte Spustit. Pak vyberte Spustit ladění.

    Aplikace by teď měla fungovat, ale pojďme zkontrolovat, jestli se JSON vytváří správně.

  10. Přejděte na (http://localhost:5000/specials) a podívejte se na:

    Snímek obrazovky s prohlížečem, který zobrazuje JSON pro pizzy

    Json obsahuje pizzy uvedené v sestupném pořadí ceny, jak je uvedeno ve speciálním kontroleru pizzy.

    snímek obrazovky znázorňující ještě více žhavé pizzy