練習 - 從 Blazor 元件存取數據
應用程式中目前的硬式編碼披薩必須以資料庫取代。 您可以使用 Microsoft Entity Framework,將連線新增至數據源。 在此應用程式中,我們使用 SQLite 資料庫來儲存披薩。
在此練習中,您會新增套件以支持資料庫功能、將類別連線到後端資料庫,以及新增協助程序類別來預先載入公司的披薩數據。
新增支援數據庫存取的套件
如果應用程式仍在執行中,請停止該應用程式。
在 Visual Studio Code 中,選取 終端機>新增終端機。
在新終端機中,將您的位置設定為 BlazingPizza 目錄。
cd BlazingPizza執行下列命令以新增 Microsoft.EntityFrameworkCore、 Microsoft.EntityFrameworkCore.Sqlite 和 System.Net.Http.Json 套件:
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這些命令會將套件參考新增至 BlazingPizza.csproj 檔案:
<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>
新增資料庫上下文
在 Visual Studio Code 中,在 BlazingPizza 資料夾中建立新的資料夾。 將它命名為 Data。
在 [數據] 資料夾中,建立名為 PizzaStoreContext.cs 的新檔案。
在新檔案中,輸入 類別的這個程式代碼:
using Microsoft.EntityFrameworkCore; namespace BlazingPizza.Data; public class PizzaStoreContext : DbContext { public PizzaStoreContext(DbContextOptions options) : base(options) { } public DbSet<PizzaSpecial> Specials { get; set; } }這個類別會建立可用來註冊資料庫服務的資料庫內容。 內容也允許我們有可存取資料庫的控制器。
使用 Ctrl+S 儲存變更。
新增控制器
在 BlazingPizza 資料夾中建立新的資料夾。 將它命名為 Controllers。
在 Controllers 資料夾中建立新的檔案。 將它命名 為SpecialsController.cs。
輸入 類別的這個程式代碼:
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(); } }這個類別會建立一個控制器,讓我們查詢資料庫的披薩特惠,並以 JSON 形式傳回至
(http://localhost:5000/specials)URL。儲存您的變更。
將數據載入資料庫
應用程式會查看是否有現有的 SQLite 資料庫,並使用一些預先製作的披薩來建立一個資料庫。
在 資料 目錄中建立新的檔案。 將它命名 為SeedData.cs。
輸入 類別的這個程式代碼:
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(); } }類使用傳遞的資料庫內容,在陣列中建立一些
PizzaSpecial物件,然後儲存。在檔案總管中,選取 [Program.cs]。
在頂端,將參考新增至新的
PizzaStoreContext:using BlazingPizza.Data;此語句可讓應用程式使用新的服務。
將此區段插入至
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();這項變更會使用
PizzaStoreContext建立資料庫範圍。 如果尚未建立資料庫,它會呼叫SeedData靜態類別來建立一個資料庫。目前,應用程式無法運作,因為
PizzaStoreContext尚未初始化 。 在 Program.cs 檔案中,在目前的服務底下新增此程式代碼(開始builder.Services.的行):builder.Services.AddHttpClient(); builder.Services.AddSqlite<PizzaStoreContext>("Data Source=pizza.db");此程式代碼會註冊兩個服務。 第一個
AddHttpClient語句可讓應用程式存取 HTTP 命令。 應用程式會使用 HttpClient 來取得披薩特價的 JSON。 第二個語句會註冊新的PizzaStoreContext,並提供 SQLite 資料庫的檔名。
使用資料庫來顯示披薩
我們現在可以在 Index.razor 頁面中取代硬式編碼的披薩。
在檔案總管中,展開 [頁面],然後選取 [Index.razor]。
將現有的
OnInitialized()方法取代為:protected override async Task OnInitializedAsync() { specials = await HttpClient.GetFromJsonAsync<List<PizzaSpecial>>(NavigationManager.BaseUri + "specials"); }Note
此程式代碼會
OnInitialized()取代為OnInitializedAsync()。 特製披薩現在會以非同步方式從應用程式傳回為 JSON。您需要修正一些錯誤。 在
@inject指示詞底下新增這些@page語句:@inject HttpClient HttpClient @inject NavigationManager NavigationManager儲存所有變更,然後選取 F5 或選取 [ 執行]。 然後選取 [開始偵錯]。
當您執行應用程式時發生運行時錯誤。 JsonReader 引發例外狀況。
請記住,應用程式應該在
(http://localhost:5000/specials)建立 JSON。 移至該 URL。應用程式不知道如何路由傳送此要求。 您要在 Blazor 路由課程模組中了解路由。 現在讓我們修正錯誤。
選取 Shift + F5,或選取 [停止偵錯]。
在檔案總管中,選取 [Program.cs]。
在檔案中間,在開始
app.的行之後,新增此端點:app.MapControllerRoute("default", "{controller=Home}/{action=Index}/{id?}");程式代碼現在應該是:
... app.MapRazorPages(); app.MapBlazorHub(); app.MapFallbackToPage("/_Host"); app.MapControllerRoute("default", "{controller=Home}/{action=Index}/{id?}"); ...選取 F5 或選取 [ 執行]。 然後選取 [開始偵錯]。
應用程式現在應該可以運作,但讓我們檢查 JSON 是否已正確建立。
移動到
(http://localhost:5000/specials)以查看:
JSON 會依照特殊披薩控制器中指定的價格遞減順序列出披薩。