演習 - 既存のデータベースからリバース エンジニアリングする

完了

Contoso Pizza のマネージャーから、アプリでクーポンを表示できるようにエンドポイントを追加するよう求められました。 クーポンは既存のデータベースに存在します。 このユニットでは、既存のデータベースからスキャフォールディングを作成し、結果のエンティティ クラスを変更します。

キャンペーン データベースを検査する

スキャフォールディングされたコードの生成に使用するデータベースを調べます。

  1. [エクスプローラー] ペインで、Promotions ディレクトリを展開し、Promotions.db ファイルを右クリックして、[データベースを開く] を選びます。

    [SQLite エクスプローラー] フォルダーで新しいデータベースが開きます。

  2. [Sqlite エクスプローラー] フォルダーで、Promotions.db ノードと Coupons ノードを展開します。 データ スキーマに注意してください。

  3. Coupons ノードを右クリックして、[Show table](テーブルの表示) を選びます。 クーポン データを調べます。

キャンペーン コンテキストとクーポン モデルをスキャフォールディングする

次に、データベースを使ってコードをスキャフォールディングします。

  1. 次のコマンドを実行します。

    dotnet ef dbcontext scaffold "Data Source=Promotions/Promotions.db" Microsoft.EntityFrameworkCore.Sqlite --context-dir Data --output-dir Models   
    

    上記のコマンドでは次のことが行われます。

    • 提供された接続文字列を使って、DbContext とモデルのクラスをスキャフォールディングします。
    • Microsoft.EntityFrameworkCore.Sqlite データベース プロバイダーを使うように指定します。
    • 結果の DbContext とモデルのクラスを格納するディレクトリを指定します。

    Note

    この演習では、接続文字列がソース コードに含まれていることに関する警告は無視してかまいません。 実際のコードでは、接続文字列はセキュリティで保護された場所に必ず格納してください。

  2. Models\Coupon.cs を開きます。 SQLite には datetime データ型がないので、Expiration プロパティは文字列として定義されています。 Expiration の型を string? から DateTime に変更します。 datetime データから string データへの変換は、EF Core によって管理されます。

    using System;
    using System.Collections.Generic;
    
    namespace ContosoPizza.Models
    {
        public partial class Coupon
        {
            public long Id { get; set; }
            public string Description { get; set; } = null!;
            public DateTime Expiration { get; set; }
        }
    }
    

    ヒント

    データベースが変更された場合は、新しいスキャフォールディングされたファイルを生成できます。 ファイルは生成されるたびに上書きされますが、partial クラスとして作成されるので、独自の別のファイル内でカスタムのプロパティと動作を使用して拡張することができます。

クーポン エンドポイントを追加する

スキャフォールディングされたコードをテストする前に、API にエンドポイントを追加する必要があります。 そこで次に、新しい API コントローラーを追加します。

API コントローラーのしくみを理解するには、「ASP.NET Core コントローラーを使用して Web API を作成する」を参照してください。

  1. Controllers フォルダーに、次のコードを含む CouponController.cs という名前のファイルを追加します。

    using ContosoPizza.Data;
    using ContosoPizza.Models;
    using Microsoft.AspNetCore.Mvc;
    using Microsoft.EntityFrameworkCore;
    
    namespace ContosoPizza.Controllers;
    
    [ApiController]
    [Route("[controller]")]
    public class CouponController : ControllerBase
    {
        PromotionsContext _context;
    
        public CouponController(PromotionsContext context)
        {
            _context = context;
        }
    
        [HttpGet]
        public IEnumerable<Coupon> Get()
        {
            return _context.Coupons
                .AsNoTracking()
                .ToList();
        }
    }
    

    このコードは、API に api/coupon エンドポイントを追加します。

    上のコードでは以下の操作が行われます。

    • PromotionsContext オブジェクトが、コンストラクターに挿入されます。
    • Get メソッドから、すべてのクーポンが返されます。
  2. Program.cs で、コメント // Add the PromotionsContext を次のコードに置き換えます。

    builder.Services.AddSqlite<PromotionsContext>("Data Source=Promotions/Promotions.db");
    

    このコードは、PromotionsContext を依存関係挿入システムに登録します。

  3. すべての変更を保存し、dotnet run を使ってアプリを実行します。

エンドポイントをテストする

これでエンドポイントが追加されたので、クーポンの操作をテストします。

  1. 前の演習で行ったように、API の Swagger UI に移動します (または、ブラウザーで既存の UI を更新します)。

  2. 見出し [クーポン] の下で、[GET] 操作を展開し、[試してみる] を選択します。

  3. [実行] を選択します。 応答本文に、データベースからのクーポンが表示されます。

    [
    {
        "id": 1,
        "description": "Buy 1 get 1 free",
        "expiration": "2025-01-01T00:00:00"
    },
    {
        "id": 2,
        "description": "4 large pizzas for $40",
        "expiration": "2024-06-30T00:00:00"
    }
    ]
    

    expiration は datetime 値であることに注意してください。

これで完了です。 既存のデータベースからスキャフォールディングを作成して変更しました。