Ćwiczenie — uzyskiwanie dostępu do danych ze składnika Blazor

Ukończone

Bieżące zakodowane pizze w aplikacji muszą zostać zastąpione bazą danych. Możesz użyć programu Microsoft Entity Framework, aby dodać połączenia ze źródłami danych. W tej aplikacji użyjemy bazy danych SQLite do przechowywania pizzy.

W tym ćwiczeniu dodasz pakiety do obsługi funkcji bazy danych, połączysz klasy z bazą danych zaplecza i dodasz klasę pomocnika, aby wstępnie załadować dane dla pizz firmy.

Dodawanie pakietów do obsługi dostępu do bazy danych

  1. Zatrzymaj aplikację, jeśli nadal jest uruchomiona.

  2. W programie Visual Studio Code wybierz pozycję Terminal New Terminal (Nowy>terminal).

  3. W nowym terminalu ustaw lokalizację na katalog BlazingPizza .

    cd BlazingPizza
    
  4. Uruchom następujące polecenia, aby dodać pakiety Microsoft.EntityFrameworkCore, Microsoft.EntityFrameworkCore.Sqlite i 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
    

    Te polecenia dodają odwołania do pakietu do pliku 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>
    

Dodawanie kontekstu bazy danych

  1. W programie Visual Studio Code utwórz nowy folder w folderze BlazingPizza . Nadaj mu nazwę Dane.

  2. Utwórz nowy plik w folderze Dane . Nadaj mu nazwę PizzaStoreContext.cs.

  3. Wprowadź ten kod dla klasy:

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

    Ta klasa tworzy kontekst bazy danych, za pomocą której można zarejestrować usługę bazy danych. Kontekst umożliwia również posiadanie kontrolera, który uzyskuje dostęp do bazy danych.

  4. Zapisz zmiany.

Dodawanie kontrolera

  1. Utwórz nowy folder w folderze BlazingPizza . Nadaj jej nazwę Kontrolery.

  2. Utwórz nowy plik w folderze Controllers . Nadaj mu nazwę SpecialsController.cs.

  3. Wprowadź ten kod dla klasy:

    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();
        }
    }
    

    Ta klasa tworzy kontroler, który umożliwia wykonywanie zapytań dotyczących bazy danych pod kątem produktów specjalnych pizzy i zwraca je jako kod JSON pod adresem (http://localhost:5000/specials) URL.

  4. Zapisz zmiany.

Ładowanie danych do bazy danych

Aplikacja sprawdza, czy istnieje istniejąca baza danych SQLite i tworzy jedną ze wstępnie utworzonymi pizzami.

  1. Utwórz nowy plik w katalogu Data . Nadaj mu nazwę SeedData.cs.

  2. Wprowadź ten kod dla klasy:

    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();
        }
    }
    

    Klasa używa przekazanego kontekstu bazy danych, tworzy niektóre PizzaSpecial obiekty w tablicy, a następnie zapisuje je.

  3. W eksploratorze plików wybierz pozycję Program.cs.

  4. W górnej części dodaj odwołanie do nowego PizzaStoreContextelementu :

    using BlazingPizza.Data;
    

    Ta instrukcja umożliwia aplikacji korzystanie z nowej usługi.

  5. Wstaw ten segment powyżej app.Run(); metody:

    ...
    // 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();
    

    Ta zmiana powoduje utworzenie zakresu bazy danych za pomocą elementu PizzaStoreContext. Jeśli baza danych nie została jeszcze utworzona, wywołuje klasę statyczną SeedData , aby ją utworzyć.

  6. W tej chwili aplikacja nie działa, ponieważ nie zainicjowaliśmy elementu PizzaStoreContext. Add Services to the container W sekcji wyższej w pliku Program.cs dodaj ten kod w ramach bieżących usług (wiersze, które rozpoczynają się builder.Services.):

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

    Ten kod rejestruje dwie usługi. Pierwsza AddHttpClient instrukcja umożliwia aplikacji dostęp do poleceń HTTP. Aplikacja używa klienta HttpClient do pobrania kodu JSON na potrzeby specjalnych pizzy. Druga instrukcja rejestruje nową PizzaStoreContext i udostępnia nazwę pliku bazy danych SQLite.

Wyświetlanie pizz za pomocą bazy danych

Teraz możemy zastąpić ustaloną pizzę na stronie Index.razor .

  1. W Eksploratorze plików wybierz pozycję Index.razor.

  2. Zastąp istniejącą OnInitialized() metodę:

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

    Uwaga

    Ten kod został zastąpiony OnInitialized() ciągiem OnInitializedAsync(). Teraz specjalne będą zwracane jako dane JSON z aplikacji asynchronicznie.

  3. Istnieją pewne błędy, które należy naprawić. Dodaj następujące @inject instrukcje zgodnie z dyrektywą @page :

    @inject HttpClient HttpClient
    @inject NavigationManager NavigationManager
    
  4. Zapisz wszystkie zmiany, a następnie wybierz pozycję F5 lub wybierz pozycję Uruchom. Następnie wybierz pozycję Rozpocznij debugowanie.

    Podczas uruchamiania aplikacji występuje błąd środowiska uruchomieniowego. Element JsonReader zgłosił wyjątek.

  5. Pamiętaj, że aplikacja powinna tworzyć kod JSON pod adresem (http://localhost:5000/specials). Przejdź do tego adresu URL.

    Aplikacja nie wie, jak kierować to żądanie. Dowiesz się więcej na temat routingu w module dotyczącym routingu platformy Blazor. Naprawmy teraz błąd.

  6. Wybierz pozycję Shift + F5 lub wybierz pozycję Zatrzymaj debugowanie.

  7. W eksploratorze plików wybierz pozycję Program.cs.

  8. W środku pliku po wierszach rozpoczynających się app.dodaj następujący punkt końcowy:

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

    Kod powinien teraz wyglądać następująco:

    ...
    app.MapRazorPages();
    app.MapBlazorHub();
    app.MapFallbackToPage("/_Host");
    app.MapControllerRoute("default", "{controller=Home}/{action=Index}/{id?}");
    ...
    
  9. Wybierz pozycję F5 lub wybierz pozycję Uruchom. Następnie wybierz pozycję Rozpocznij debugowanie.

    Aplikacja powinna teraz działać, ale sprawdźmy, czy kod JSON jest tworzony poprawnie.

  10. Przejdź do strony, (http://localhost:5000/specials) aby zobaczyć:

    Screenshot showing the browser that shows JSON for pizzas.

    Kod JSON zawiera pizze wymienione w kolejności malejącej ceny, jak określono w specjalnym kontrolerze pizzy.

    Screenshot showing even more blazing pizzas.