演習 - 最小 API に EF Core を追加する

完了

あなたは会社の開発者であり、あなたとあなたの会社は新しい最小限の API について聞いたことがあります。 次のプロジェクトでプロジェクトを使用するかどうかを話し合うことができるように、マネージャーからプロジェクトの作成を依頼されました。

このモジュールでは、ローカル開発に .NET CLI (コマンド ライン インターフェイス) と Visual Studio Code を使用します。 このモジュールを終了すると、Visual Studio (Windows)、Visual Studio for Mac (macOS)、または Visual Studio Code (Windows、Linux、macOS) を使った継続的開発を使用して、その概念を適用できます。

このモジュールでは、.NET 8.0 SDK を使います。 適切なコマンド ターミナルで次のコマンドを実行して、.NET 8.0 がインストールされていることを確認します。

dotnet --list-sdks

次の例のような出力が表示されます。

6.0.317 [C:\Program Files\dotnet\sdk]
7.0.401 [C:\Program Files\dotnet\sdk]
8.0.100 [C:\Program Files\dotnet\sdk]

8 で始まるバージョンが一覧に表示されていることを確実にします。 何も表示されていない場合、またはコマンドが見つからない場合は、 最新の .NET 8.0 SDK をインストールします。

プロジェクトのセットアップ

まず、プロジェクトを作成する必要があります。 .NET 6 をインストールしたので、準備ができました。 このユニットでは、ピザ管理 API にデータ永続化を追加します。

  1. ターミナルで、次の dotnet newを実行して Web API を作成します。

    dotnet new web -o PizzaStore -f net8.0
    

    PizzaStore ディレクトリが表示されます。

  2. 次のコマンドを入力して PizzaStore ディレクトリに移動します。

    cd PizzaStore
    
  3. Swashbuckle パッケージをインストールします。

    dotnet add package Swashbuckle.AspNetCore --version 6.5.0
    
  4. Visual Studio Code でプロジェクトを開きます。

  5. Visual Studio Code を使用して、プロジェクト ルートに Pizza.cs ファイルを作成し、次の内容を指定します。

    namespace PizzaStore.Models 
    {
        public class Pizza
        {
              public int Id { get; set; }
              public string? Name { get; set; }
              public string? Description { get; set; }
        }
    }
    

    上記の Pizza クラスは、ピザを表す単純なオブジェクトです。 このコードはデータ モデルです。 後で Entity Framework (EF) Core を使用して、このデータ モデルをデータベース テーブルにマップします。

  6. Program.csを開き、強調表示されたコードを追加します。

    using Microsoft.OpenApi.Models;
    
    var builder = WebApplication.CreateBuilder(args);
    
    builder.Services.AddEndpointsApiExplorer();
    builder.Services.AddSwaggerGen(c =>
    {
         c.SwaggerDoc("v1", new OpenApiInfo {
             Title = "PizzaStore API",
             Description = "Making the Pizzas you love",
             Version = "v1" });
    });
    
    var app = builder.Build();
    if (app.Environment.IsDevelopment())
    {
       app.UseSwagger();
       app.UseSwaggerUI(c =>
       {
          c.SwaggerEndpoint("/swagger/v1/swagger.json", "PizzaStore API V1");
       });
    }
    
    app.MapGet("/", () => "Hello World!");
    
    app.Run();
    

    Visual Studio Code で、プロジェクトをデバッグするためのアセットを追加するように求めるプロンプトが表示される場合があります。 ダイアログで Yes を選択します。

EF Core をプロジェクトに追加する

to-do リストに項目を格納するには、 EntityFrameworkCore.InMemory パッケージをインストールします。

  1. Ctrl キーを押しながら' キーを押して、Visual Studio Code でターミナルを開きます。 新しいターミナルで、次のコードを入力して EF Core InMemory パッケージを追加します。

    dotnet add package Microsoft.EntityFrameworkCore.InMemory --version 8.0
    
  2. Program.csファイルとusing Microsoft.EntityFrameworkCore;ファイルの先頭にを追加します。

    EF Core がプロジェクトに追加されたので、保存してクエリを実行するデータにコードを接続できます。 この手順を実行するには、 PizzaDb クラスを作成します。 PizzaDb クラスは、次のタスクを実行します。

    • データベース内のPizzasの一覧から Pizza プロパティを公開します。
    • UseInMemoryDatabaseを使用して、インメモリ データベース ストレージを接続します。 アプリが実行されている限り、データはここに格納されます。
  3. メモリ内データベースを設定するには、Pizza.cs ファイルの下部 (最後のの上) に次のコードを追加します。 PizzaStore.Models名前空間内に 2 つのクラス定義があります。

    class PizzaDb : DbContext
    {
        public PizzaDb(DbContextOptions options) : base(options) { }
        public DbSet<Pizza> Pizzas { get; set; } = null!;
    }
    

    DbContext は、データベース内のエンティティのインスタンスのクエリと保存に使用される接続またはセッションを表します。

  4. Program.cs ファイルの先頭にusing PizzaStore.Models;を追加します。

  5. Program.csで、AddSwaggerGenの呼び出しの前に、次のコードを追加します。

    builder.Services.AddDbContext<PizzaDb>(options => options.UseInMemoryDatabase("items"));
    

項目の一覧を返す

  • ピザ リスト内の項目の一覧から読み取るために、"/pizzas" ルートを追加する app.Run(); の呼び出しの上に次のコードを追加します。

    app.MapGet("/pizzas", async (PizzaDb db) => await db.Pizzas.ToListAsync());
    

アプリケーションを実行する

  1. すべての変更を保存したことを確認します。 ターミナルで dotnet run を呼び出してアプリを実行します。 このアクションにより、アプリがビルドされ、5000 から 5300 のポートでホストされます。 HTTPS には、7000 から 7300 の範囲でポートが選択されます。

    ランダム ポート選択動作をオーバーライドする場合は、 launchSettings.jsonで使用するポートを設定できます。

    dotnet run
    

    ターミナルでの出力の外観を次に示します。

    Building...
     info: Microsoft.Hosting.Lifetime[14]
           Now listening on: https://localhost:7200
     info: Microsoft.Hosting.Lifetime[14]
           Now listening on: http://localhost:5100
     info: Microsoft.Hosting.Lifetime[0]
           Application started. Press Ctrl+C to shut down.
     info: Microsoft.Hosting.Lifetime[0]
           Hosting environment: Development
     info: Microsoft.Hosting.Lifetime[0]
           Content root path: /<path>/PizzaStore
    
  2. ブラウザーで https://localhost:{PORT}/swagger に移動します。 [ GET /pizzas ] ボタンを選択し、[ 試してみる ] と [実行] の順に選択します。 Response bodyの下にリストが空であることがわかります。

  3. ターミナルで、 Ctrl キーを押しながら C キー を押してプログラムの実行を停止します。

新しい項目を作成する

ピザの一覧に新しい項目を POST するコードを追加してみましょう。 Program.csで、前に作成したapp.MapGetの下に次のコードを追加します。

app.MapPost("/pizza", async (PizzaDb db, Pizza pizza) =>
{
    await db.Pizzas.AddAsync(pizza);
    await db.SaveChangesAsync();
    return Results.Created($"/pizza/{pizza.Id}", pizza);
});

API のテスト

すべての変更が保存されていることを確認し、アプリをもう一度実行します。 Swagger UI に戻ると、 POST/pizzaが表示されます。 ピザリストに新しいアイテムを追加するには:

  1. POST /pizza を選択します。

  2. [ 試してみる] を選択します。

  3. 要求本文を次の JSON に置き換えます。

    {
        "name": "Pepperoni",
        "description": "A classic pepperoni pizza"
    }
    
  4. [ 実行] を選択します。

リスト内の項目を読み取る方法:

  1. GET /pizzas を選択します

  2. [ 試してみる] を選択します。

  3. [ 実行] を選択します。

    Response bodyには、追加した項目が含まれます。

    [
      {
        "id": 1,
        "name": "Pepperoni",
        "description": "A classic pepperoni pizza"
      }
    ]
    
  4. ターミナルで Ctrl キーを押しながら C キーを押して、アプリの実行を停止します。 この演習の残りの部分では、必要に応じてアプリを停止して再起動し、変更をテストします。 dotnet runする前に、すべての変更を保存してください。

1 つの項目を取得する

idで項目を取得するには、前に作成したapp.MapPost ルートの下にコードを追加します。

app.MapGet("/pizza/{id}", async (PizzaDb db, int id) => await db.Pizzas.FindAsync(id));

ID による GET のテスト

この操作をテストするには、 https://localhost:{PORT}/pizza/1 に移動するか、Swagger UI を使用します。 メモリ内データベースを使用しているため、アプリケーションを再起動した場合、以前に作成したピザは一覧表示されません。 そのため、POST 操作を使用してもう一度追加する必要があります。

項目を更新します

既存の項目を更新するには、作成した GET /pizza/{id} ルートの下にコードを追加します。

app.MapPut("/pizza/{id}", async (PizzaDb db, Pizza updatepizza, int id) =>
{
      var pizza = await db.Pizzas.FindAsync(id);
      if (pizza is null) return Results.NotFound();
      pizza.Name = updatepizza.Name;
      pizza.Description = updatepizza.Description;
      await db.SaveChangesAsync();
      return Results.NoContent();
});

PUT のテスト

  1. Swagger UI で PUT /pizza/{id} を選択します。

  2. [ 試してみる] を選択します。

  3. ID テキスト ボックスに「1」と入力します。

  4. 最後に、 Request bodyを更新します。 次の JSON を貼り付け、 namePineapple に変更します。

    {
       "id": 1,
       "name": "Pineapple"
    }
    
  5. [ 実行] を選択します。

コードをテストするには、戻って GET /pizza/{id}までスクロールします。 ピザの名前が Pineappleになりました。

項目を削除する

既存の項目を削除するには、前に作成した PUT /pizza/{id} の下にコードを追加します。

app.MapDelete("/pizza/{id}", async (PizzaDb db, int id) =>
{
   var pizza = await db.Pizzas.FindAsync(id);
   if (pizza is null)
   {
      return Results.NotFound();
   }
   db.Pizzas.Remove(pizza);
   await db.SaveChangesAsync();
   return Results.Ok();
});

DELETEをテストする

次に、Swagger インターフェイスを使用して項目を削除してみてください。

このユニットでは、EF Core を既存の最小限の API アプリケーションに追加し、メモリ内データベースを使用してデータを格納しました。 次に、実際のデータベースを使用してデータを格納し、アプリケーションのシャットダウン間に保持されるようにする方法について説明します。