演習 - Blazor コンポーネントからデータにアクセスする

完了

アプリ内の現在のハードコーディングされたピザをデータベースに置き換える必要があります。 Microsoft Entity Framework を使用して、データ ソースへの接続を追加できます。 このアプリでは、SQLite データベースを使用してピザを格納します。

この演習では、データベース機能をサポートするパッケージを追加し、クラスをバックエンド データベースに接続し、会社のピザのデータをプリロードするヘルパー クラスを追加します。

データベース アクセスをサポートするパッケージを追加する

  1. アプリがまだ実行されている場合は停止します。

  2. Visual Studio Code で、[ ターミナル>新しいターミナル] を選択します。

  3. 新しいターミナルで、場所を BlazingPizza ディレクトリに設定します。

    cd BlazingPizza
    
  4. 次のコマンドを実行して、 Microsoft.EntityFrameworkCoreMicrosoft.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>
    

データベース コンテキストの追加

  1. Visual Studio Code で、 BlazingPizza フォルダーに新しいフォルダーを作成します。 データに名前を付 けます

  2. [データ] フォルダーに、PizzaStoreContext.csという名前の新しいファイルを作成します。

  3. 新しいファイルに、クラスの次のコードを入力します。

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

    このクラスは、データベース サービスの登録に使用できるデータベース コンテキストを作成します。 コンテキストを使用すると、データベースにアクセスするコントローラーを持つことができます。

  4. を使用して変更を保存+。

コントローラーの追加

  1. BlazingPizza フォルダーに新しいフォルダーを作成します。 コントローラーと名付けます。

  2. Controllers フォルダーに新しいファイルを作成します。 SpecialsController.cs という名前を付けてください。

  3. クラスの次のコードを入力します。

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

    このクラスは、ピザのスペシャルをデータベースに照会し、 (http://localhost:5000/specials) URL で JSON として返すコントローラーを作成します。

  4. 変更を保存します。

データベースにデータを読み込む

アプリは、既存の SQLite データベースがあるかどうかを確認し、いくつかの事前に作成されたピザを含むデータベースを作成します。

  1. データ ディレクトリに新しいファイルを作成します。 SeedData.cs名前を付けます。

  2. クラスの次のコードを入力します。

    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 オブジェクトを作成し、それらを保存します。

  3. エクスプローラーで、 Program.csを選択します。

  4. 上部に、新しい PizzaStoreContextへの参照を追加します。

    using BlazingPizza.Data;
    

    このステートメントにより、アプリは新しいサービスを使用できます。

  5. 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 静的クラスを呼び出して作成します。

  6. 現時点では、 PizzaStoreContext がまだ初期化されていないため、アプリは機能しません。 Program.cs ファイルで、現在のサービス (builder.Services.を開始する行) の下に次のコードを追加します。

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

    このコードは、2 つのサービスを登録します。 最初の AddHttpClient ステートメントを使用すると、アプリは HTTP コマンドにアクセスできます。 アプリは HttpClient を使用してピザのスペシャルの JSON を取得します。 2 番目のステートメントは、新しい PizzaStoreContext を登録し、SQLite データベースのファイル名を提供します。

データベースを使用してピザを表示する

これで、Index.razor ページでハードコーディングされたピザを置き換えることができます。

  1. エクスプローラーで [ ページ] を展開し、[ Index.razor] を選択します。

  2. 既存の OnInitialized() メソッドを次のように置き換えます。

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

    Note

    このコードは、 OnInitialized()OnInitializedAsync()に置き換えます。 スペシャルは、アプリから JSON として非同期的に返されるようになります。

  3. 修正する必要があるエラーがいくつかあります。 @inject ディレクティブの下に、次の@pageステートメントを追加します。

    @inject HttpClient HttpClient
    @inject NavigationManager NavigationManager
    
  4. すべての変更を保存し、 F5 キーを押すか、[ 実行] を選択します。 次に、[ デバッグの開始] を選択します。

    アプリを実行すると、ランタイム エラーが発生します。 JsonReader によって例外が発生しました。

  5. アプリは、 (http://localhost:5000/specials)で JSON を作成する必要があります。 その URL に移動します。

    アプリは、この要求をルーティングする方法を知りません。 Blazor ルーティングのモジュールでのルーティングについて説明します。 ここでエラーを修正しましょう。

  6. Shift + F5 を選択するか、[デバッグの停止] を選択します。

  7. エクスプローラーで、 Program.csを選択します。

  8. ファイルの中央付近で、 app.開始する行の後に、次のエンドポイントを追加します。

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

    コードは次のようになります。

    ...
    app.MapRazorPages();
    app.MapBlazorHub();
    app.MapFallbackToPage("/_Host");
    app.MapControllerRoute("default", "{controller=Home}/{action=Index}/{id?}");
    ...
    
  9. F5 キーを押すか、[実行] を選択します。 次に、[ デバッグの開始] を選択します。

    これでアプリは動作するはずですが、JSON が正しく作成されていることを確認しましょう。

  10. (http://localhost:5000/specials)に移動すると、次の情報が表示されます。

    ピザの JSON を示すブラウザーを示すスクリーンショット。

    JSON には、特別なピザ コントローラーで指定されている価格の降順にピザが一覧表示されます。

    さらに燃えるピザを示すスクリーンショット。