Ćwiczenie — uzyskiwanie dostępu do danych ze składnika Blazor
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
Zatrzymaj aplikację, jeśli nadal jest uruchomiona.
W programie Visual Studio Code wybierz pozycję Terminal New Terminal (Nowy>terminal).
W nowym terminalu ustaw lokalizację na katalog BlazingPizza .
cd BlazingPizza
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
W programie Visual Studio Code utwórz nowy folder w folderze BlazingPizza . Nadaj mu nazwę Dane.
Utwórz nowy plik w folderze Dane . Nadaj mu nazwę PizzaStoreContext.cs.
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.
Zapisz zmiany.
Dodawanie kontrolera
Utwórz nowy folder w folderze BlazingPizza . Nadaj jej nazwę Kontrolery.
Utwórz nowy plik w folderze Controllers . Nadaj mu nazwę SpecialsController.cs.
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.Zapisz zmiany.
Ładowanie danych do bazy danych
Aplikacja sprawdza, czy istnieje istniejąca baza danych SQLite i tworzy jedną ze wstępnie utworzonymi pizzami.
Utwórz nowy plik w katalogu Data . Nadaj mu nazwę SeedData.cs.
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.W eksploratorze plików wybierz pozycję Program.cs.
W górnej części dodaj odwołanie do nowego
PizzaStoreContext
elementu :using BlazingPizza.Data;
Ta instrukcja umożliwia aplikacji korzystanie z nowej usługi.
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ć.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 .
W Eksploratorze plików wybierz pozycję Index.razor.
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ągiemOnInitializedAsync()
. Teraz specjalne będą zwracane jako dane JSON z aplikacji asynchronicznie.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
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.
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.
Wybierz pozycję Shift + F5 lub wybierz pozycję Zatrzymaj debugowanie.
W eksploratorze plików wybierz pozycję Program.cs.
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?}"); ...
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.
Przejdź do strony,
(http://localhost:5000/specials)
aby zobaczyć:Kod JSON zawiera pizze wymienione w kolejności malejącej ceny, jak określono w specjalnym kontrolerze pizzy.