Übung – Zugreifen auf Daten aus einer Blazor-Komponente

Abgeschlossen

Die aktuellen hartkodierten Pizzen in der App müssen durch eine Datenbank ersetzt werden. Sie können microsoft Entity Framework verwenden, um Verbindungen zu Datenquellen hinzuzufügen. In dieser App verwenden wir eine SQLite-Datenbank, um die Pizza zu speichern.

In dieser Übung fügen Sie Pakete hinzu, um Datenbankfunktionen zu unterstützen, Klassen mit einer Back-End-Datenbank zu verbinden und eine Hilfsklasse zum Vorabladen von Daten für die Pizza des Unternehmens hinzuzufügen.

Hinzufügen von Paketen, die den Datenbankzugriff unterstützen

  1. Beenden Sie die App, wenn sie noch ausgeführt wird.

  2. Wählen Sie in Visual Studio Code "Terminal>New Terminal" aus.

  3. Legen Sie im neuen Terminal Ihren Standort auf das BlazingPizza-Verzeichnis fest.

    cd BlazingPizza
    
  4. Führen Sie die folgenden Befehle aus, um die Pakete "Microsoft.EntityFrameworkCore", "Microsoft.EntityFrameworkCore.Sqlite" und "System.Net.Http.Json" hinzuzufügen:

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

    Diese Befehle fügen Paketverweise zu Ihrer Datei BlazingPizza.csproj hinzu:

      <ItemGroup>
        <PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.0-*" />
        <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="9.0.0-*" />
        <PackageReference Include="System.Net.Http.Json" Version="9.0.0-*" />
      </ItemGroup>
    

Hinzufügen eines Datenbankkontexts

  1. Erstellen Sie in Visual Studio Code einen neuen Ordner im Ordner "BlazingPizza ". Benennen Sie die Daten.

  2. Erstellen Sie im Ordner "Daten " eine neue Datei mit dem Namen PizzaStoreContext.cs.

  3. Geben Sie in der neuen Datei diesen Code für die Klasse ein:

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

    Diese Klasse erstellt einen Datenbankkontext, den wir zum Registrieren eines Datenbankdiensts verwenden können. Der Kontext ermöglicht es uns auch, einen Controller zu haben, der auf die Datenbank zugreift.

  4. Speichern Sie Ihre Änderungen mit STRG+S.

Hinzufügen eines Controllers

  1. Erstellen Sie einen neuen Ordner im Ordner "BlazingPizza ". Nennen Sie ihn Controllers.

  2. Erstellen Sie eine neue Datei im Ordner "Controller ". Benennen Sie ihn SpecialsController.cs.

  3. Geben Sie diesen Code für die Klasse ein:

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

    Diese Klasse erstellt einen Controller, der es uns ermöglicht, die Datenbank nach Pizza-Specials abzufragen und sie als JSON an der (http://localhost:5000/specials) URL zurückzugeben.

  4. Speichern Sie Ihre Änderungen.

Laden von Daten in die Datenbank

Die App überprüft, ob eine vorhandene SQLite-Datenbank vorhanden ist und eine mit einigen vorgefertigten Pizzas erstellt wird.

  1. Erstellen Sie eine neue Datei im Datenverzeichnis . Nennen Sie ihn SeedData.cs.

  2. Geben Sie diesen Code für die Klasse ein:

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

    Die Klasse verwendet einen übergebenen Datenbankkontext, erstellt einige PizzaSpecial Objekte in einem Array und speichert sie dann.

  3. Wählen Sie im Datei-Explorer Program.cs aus.

  4. Fügen Sie oben einen Verweis auf ein neues PizzaStoreContexthinzu:

    using BlazingPizza.Data;
    

    Mit dieser Anweisung kann die App den neuen Dienst verwenden.

  5. Fügen Sie dieses Segment oberhalb der app.Run(); Methode ein:

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

    Diese Änderung erstellt einen Datenbankbereich mit dem PizzaStoreContext. Wenn noch keine Datenbank erstellt wurde, wird die SeedData statische Klasse aufgerufen, um eine datenbank zu erstellen.

  6. Derzeit funktioniert die App nicht, da die PizzaStoreContext App noch nicht initialisiert ist. Fügen Sie in der datei Program.cs diesen Code unter den aktuellen Diensten hinzu (die Zeilen, die beginnen builder.Services.):

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

    Dieser Code registriert zwei Dienste. Die erste AddHttpClient Anweisung ermöglicht der App den Zugriff auf HTTP-Befehle. Die App verwendet einen HttpClient, um den JSON-Code für Pizza-Specials abzurufen. Die zweite Anweisung registriert das neue PizzaStoreContext Und stellt den Dateinamen für die SQLite-Datenbank bereit.

Verwenden der Datenbank zum Anzeigen von Pizzas

Jetzt kann die hartcodierte Pizza auf der Seite Index.razor ersetzt werden.

  1. Erweitern Sie im Datei-Explorer Seiten, und wählen Sie dann "Index.razor" aus.

  2. Ersetzen Sie die vorhandene OnInitialized() Methode durch:

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

    Note

    Dieser Code ersetzt OnInitialized() durch OnInitializedAsync(). Specials werden nun asynchron als JSON aus der App zurückgegeben.

  3. Es gibt einige Fehler, die Sie beheben müssen. Fügen Sie diese @inject-Anweisungen unter der @page-Anweisung hinzu:

    @inject HttpClient HttpClient
    @inject NavigationManager NavigationManager
    
  4. Speichern Sie alle Ihre Änderungen, und wählen Sie dann F5 aus, oder wählen Sie "Ausführen" aus. Wählen Sie dann "Debuggen starten" aus.

    Beim Ausführen der App ist ein Laufzeitfehler aufgetreten. Der JsonReader hat eine Ausnahme ausgelöst.

  5. Denken Sie daran, dass die App JSON bei (http://localhost:5000/specials) erstellen sollte. Wechseln Sie zu dieser URL.

    Die App weiß nicht, wie diese Anforderung weitergeleitet wird. Sie erfahren mehr über Routing im Modul über Blazor Routing. Lassen Sie uns den Fehler jetzt beheben.

  6. Wählen Sie Shift + F5, oder wählen Sie Debuggen beenden.

  7. Wählen Sie im Datei-Explorer Program.cs aus.

  8. Fügen Sie in der Mitte der Datei nach den Zeilen, die beginnen app., diesen Endpunkt hinzu:

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

    Der Code sollte jetzt folgendes sein:

    ...
    app.MapRazorPages();
    app.MapBlazorHub();
    app.MapFallbackToPage("/_Host");
    app.MapControllerRoute("default", "{controller=Home}/{action=Index}/{id?}");
    ...
    
  9. Wählen Sie F5 aus, oder wählen Sie "Ausführen" aus. Wählen Sie dann "Debuggen starten" aus.

    Die App sollte jetzt funktionieren, aber wir überprüfen, ob der JSON-Code ordnungsgemäß erstellt wird.

  10. Gehen Sie zu (http://localhost:5000/specials), um zu sehen:

    Screenshot des Browsers, der JSON für Pizzas anzeigt.

    Der JSON-Code enthält die Pizzas in absteigender Reihenfolge des Preises, wie im speziellen Pizzacontroller angegeben.

    Screenshot, der noch mehr flammende Pizzas zeigt.