演習 - 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 6.0.8 dotnet add package Microsoft.EntityFrameworkCore.Sqlite --version 6.0.8 dotnet add package System.Net.Http.Json --version 6.0.0
これらのコマンドによって、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>
データベース コンテキストの追加
Visual Studio Code で、BlazingPizza フォルダーに新しいフォルダーを作成します。 これに Data という名前を付けます。
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; } }
このクラスでは、データベース サービスを登録するために使用できるデータベース コンテキストを作成します。 コンテキストにより、データベースにアクセスするコントローラーも使用できるようになります。
変更を保存します。
コントローラーの追加
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(); } }
このクラスでは、データベースに対してスペシャル ピザのクエリを実行し、URL
(http://localhost:5000/specials)
に JSON としてそれらを返すことができるようにするコントローラーを作成します。変更を保存します。
データベースにデータを読み込む
アプリによって、既存の SQLite データベースがあるかどうかが確認され、あらかじめ作成されているいくつかのピザでそれが作成されます。
Data ディレクトリに新しいファイルを作成します。 それに 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 ファイルの上の方のAdd Services to the container
セクションで、現在のサービス (builder.Services.
で始まる行) の下に次のコードを追加します。builder.Services.AddHttpClient(); builder.Services.AddSqlite<PizzaStoreContext>("Data Source=pizza.db");
このコードでは、2 つのサービスを登録します。 最初の
AddHttpClient
ステートメントにより、アプリで HTTP コマンドにアクセスできます。 アプリで HttpClient を使用して、スペシャル ピザの JSON を取得します。 2 つ目のステートメントにより、新しいPizzaStoreContext
が登録され、SQLite データベースのファイル名が提供されます。
データベースを使用してピザを表示する
ここで、Index.razor ページにハードコーディングされたピザを置き換えることができます。
エクスプローラーで Index.razor を選びます。
既存の
OnInitialized()
メソッドを次に置き換えます。protected override async Task OnInitializedAsync() { specials = await HttpClient.GetFromJsonAsync<List<PizzaSpecial>>(NavigationManager.BaseUri + "specials"); }
注意
このコードでは
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 には、スペシャル ピザ コントローラーで指定されたとおりに、価格の降順でピザの一覧が列挙されています。