演習 - データ ストアを追加する

在庫内の犬用のおもちゃを表すには、Model というクラスの種類が必要です。 Model は、製品のプロパティを含んでいる必要があり、Web API にデータを渡すために使用されます。 また、Model は、データ ストアに犬用のおもちゃを保持するためにも使用されます。 このユニットでは、メモリ内の EF Core データベースとして、そのデータ ストアを作成します。

このユニットでは、簡単にするためにメモリ内データベースを使用します。 運用環境では、SQL Server や Azure SQL Database などの別のデータ ストアを選択します。

重要

Cloud Shell セッションがタイム アウトになったか切断された場合、再接続し、再接続した後に次のコマンドを実行して作業ディレクトリを ~/contoso-pets/src/ContosoPets.Api に設定し、エディターを起動します。

cd ~/contoso-pets/src/ContosoPets.Api && code .
  1. 次のコマンドを実行します。

    mkdir Models && touch $_/Product.cs
    

    注意

    touch は、Cloud Shell の基になっている OS である Linux に固有のコマンドです。

    プロジェクトのルートに、Models ディレクトリと空の Product.cs ファイルが作成されます。 ディレクトリ名 Models は規則です。 ディレクトリ名の由来は、Web API で使用されている Model-View-Controller アーキテクチャです。

  2. エディターの更新アイコンをクリックして、エクスプローラーを更新します。

    Cloud Shell の更新アイコン

    Models ディレクトリとその Product.cs ファイルが表示されます。

  3. 製品を定義するための次のコードを Models/Product.cs に追加します。 変更を保存します。

    using System.ComponentModel.DataAnnotations;
    
    namespace ContosoPets.Api.Models
    {
        public class Product
        {
            public long Id { get; set; }
    
            [Required]
            public string Name { get; set; }
    
            [Required]
            [Range(minimum: 0.01, maximum: (double) decimal.MaxValue)]
            public decimal Price { get; set; }
        }
    }
    

    ヒント

    次のキーボード ショートカットは、Cloud Shell エディター内で役立ちます。

    キーボード ショートカット コマンド
    Ctrl + V (Windows)
    ⌘ + V (macOS)
    貼り付け
    Ctrl + S (Windows)
    ⌘ + S (macOS)
    保存

    Name プロパティと Price プロパティは、Product オブジェクトを作成するときに値が確実に指定されるように、必須としてマークされています。 さらに、Price プロパティでは、最小値と最大値が適用されます。

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

    mkdir Data && touch $_/ContosoPetsContext.cs $_/SeedData.cs
    

    プロジェクトのルートに、Data ディレクトリと空の ContosoPetsContext.cs および SeedData.cs ファイルが作成されます。

  5. ファイル エクスプローラーを最新の情報に更新し、次のコードを Data/ContosoPetsContext.cs に追加します。 変更を保存します。

    using Microsoft.EntityFrameworkCore;
    using ContosoPets.Api.Models;
    
    namespace ContosoPets.Api.Data
    {
        public class ContosoPetsContext : DbContext
        {
            public ContosoPetsContext(DbContextOptions<ContosoPetsContext> options)
                : base(options)
            {
            }
    
            public DbSet<Product> Products { get; set; }
        }
    }
    

    上記のコードにより、Contoso Pets の EF Core DbContext オブジェクトの製品固有の実装が作成されます。 次のステップで構成するように、ContosoPetsContext クラスではメモリ内データベースへのアクセスが提供されます。

  6. Startup.cs ファイルの ConfigureServices メソッドに、次の強調表示されているコードを追加します。 変更を保存します。

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddDbContext<ContosoPetsContext>(options =>
            options.UseInMemoryDatabase("ContosoPets"));
        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
    }
    

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

    • ContosoPetsContext という名前のカスタム DbContext クラスを、ASP.NET Core の依存関係挿入システムに登録します。
    • ContosoPets という名前のメモリ内データベースを定義します。
  7. 次のコードを Startup.cs の先頭に追加します。 変更を保存します。

    using Microsoft.EntityFrameworkCore;
    using ContosoPets.Api.Data;
    

    Microsoft.EntityFrameworkCore 名前空間では、UseInMemoryDatabase メソッドの呼び出しが解決されます。 ContosoPets.Api.Data 名前空間では、ContosoPetsContext の参照が解決されます。

  8. Data/SeedData.cs に次のコードを追加します。 変更を保存します。

    using System;
    using System.Linq;
    using Microsoft.EntityFrameworkCore;
    using Microsoft.Extensions.DependencyInjection;
    using ContosoPets.Api.Models;
    
    namespace ContosoPets.Api.Data
    {
        public static class SeedData
        {
            public static void Initialize(ContosoPetsContext context)
            {
                if (!context.Products.Any())
                {
                    context.Products.AddRange(
                        new Product
                        {
                            Name = "Squeaky Bone",
                            Price = 20.99m
                        },
                        new Product
                        {
                            Name = "Knotted Rope",
                            Price = 12.99m
                        }
                    );
    
                    context.SaveChanges();
                }
            }
        }
    }
    

    上記のコードでは、静的な SeedData クラスが定義されています。 そのクラスの Initialize メソッドでは、メモリ内データベースに 2 つの犬用おもちゃがシードされます。

  9. Program.cs のコードを次のコードに置き換えます。 変更を保存します。

    using System;
    using Microsoft.AspNetCore;
    using Microsoft.AspNetCore.Hosting;
    using Microsoft.Extensions.DependencyInjection;
    using Microsoft.Extensions.Logging;
    using ContosoPets.Api.Data;
    
    namespace ContosoPets.Api
    {
        public class Program
        {
            public static void Main(string[] args)
            {
                var host = CreateWebHostBuilder(args).Build();
                SeedDatabase(host);
                host.Run();
            }
    
            public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
                WebHost.CreateDefaultBuilder(args)
                    .UseStartup<Startup>();
    
            private static void SeedDatabase(IWebHost host)
            {
                var scopeFactory = host.Services.GetRequiredService<IServiceScopeFactory>();
    
                using (var scope = scopeFactory.CreateScope())
                {
                    var context = scope.ServiceProvider.GetRequiredService<ContosoPetsContext>();
    
                    if (context.Database.EnsureCreated())
                    {
                        try
                        {
                            SeedData.Initialize(context);
                        }
                        catch (Exception ex)
                        {
                            var logger = scope.ServiceProvider.GetRequiredService<ILogger<Program>>();
                            logger.LogError(ex, "A database seeding error occurred.");
                        }
                    }
                }
            }
        }
    }
    

    Program.Main メソッドは、アプリを開始すると最初に実行されるコードです。 上記の変更により、SeedData.Initialize の呼び出しによってメモリ内データベースのシード処理がトリガーされます。

    重要

    このデータベース シード処理戦略は、運用環境にはお勧めしません。 代わりに、データベース展開中のシード処理を検討してください。

  10. 次のコマンドを実行して、アプリをビルドします。

    dotnet build
    

    ビルドは警告なしで成功します。 ビルドに失敗した場合は、出力でトラブルシューティング情報を確認してください。

Product モデルと ContosoPetsContext クラスは、次のユニットで作成されるコントローラーによって使用されます。