LoginSignup
3
2

More than 3 years have passed since last update.

ASP.NET Core 3.0 Razor Pages 事始め(6) - データベースに初期値を設定する

Last updated at Posted at 2019-11-07

記事目次

  1. ASP.NET Core 3.0 Razor Pages 事始め(1) - はじめてのRazor Pagesアプリケーション
  2. ASP.NET Core 3.0 Razor Pages 事始め(2) - スキャフォールディングとDBマイグレーション
  3. ASP.NET Core 3.0 Razor Pages 事始め(3) - マイグレーションのやり直しとURLルーティング
  4. ASP.NET Core 3.0 Razor Pages 事始め(4) - ページモデルとページハンドラ
  5. ASP.NET Core 3.0 Razor Pages 事始め(5) - Postページハンドラとタグヘルパー
  6. ASP.NET Core 3.0 Razor Pages 事始め(6) - データベースに初期値を設定する <-- この記事
  7. ASP.NET Core 3.0 Razor Pages 事始め(7) - Viewの変更とコンカレンシー例外処理
  8. ASP.NET Core 3.0 Razor Pages 事始め(8) - 検索機能の追加
  9. ASP.NET Core 3.0 Razor Pages 事始め(9) - ページに新しいフィールドを追加する
  10. ASP.NET Core 3.0 Razor Pages 事始め(10) - 検証機能の追加

今回は、公式チュートリアルのデータベースと ASP.NET Core を使用するをやっていこうと思います。

データベース接続のための設定

Startup.cs の ConfigureServices メソッドを見てみます。

最初に実施したスキャフォールディングの操作で、ConfigureServices メソッドに以下の行が追加されています。

services.AddDbContext<RazorPagesMovieContext>(options =>
    options.UseSqlite(Configuration.GetConnectionString("MovieContext")));

このコードにより、データベースコンテキストとして、RazorPagesMovieContext がアプリに組み込まれます。
ここでは、オプションでSQLiteを利用することを指定しています。

Configuration.GetConnectionString("MovieContext") で接続文字列を構成ファイル(appsettings.json)から取得しています。

これらのコードによって、RazorPagesMovieContextのインスタンスをランタイムが生成してくれます。
自身でインスタンスを生成する必要はありません。

DbContextの利用

各Pageモデルでは、コンストラクタの引数で、このインスタンスを受け取ることができます。

例えば、Index.cshtml.csだと、以下のコードのように、コンストラクタで、RazorPagesMovieContextのインスタンスを受け取っています。

public class IndexModel : PageModel
{
    private readonly RazorPagesMovie.Models.RazorPagesMovieContext _context;

    public IndexModel(RazorPagesMovie.Models.RazorPagesMovieContext context)
    {
        _context = context;
    }
    ……

チュートリアルのページによると、

テストサーバーまたは運用サーバーにデプロイされると、環境変数を使用して接続文字列を実際のデータベース サーバーに設定できます。

とのことです。この辺りは、ASP.NET MVC5とは異なりますね。
具体的にどうやるのか調べたいところですが、前回、前々回のように脇道にそれていると、なかなか進まないので、必要になった時に、このあたりも調べようと思います。

データベースのシード

初期データをインサートする処理を作成します。そのため、Modelsフォルダに、SeedDataという名前のクラスを新規作成します。

SeedDataクラスのコードは以下のとおりです。

using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Linq;
using RazorPagesMovie.Data;

namespace RazorPagesMovie.Models
{
    public static class SeedData
    {
        public static void Initialize(IServiceProvider serviceProvider)
        {
            using (var context = new RazorPagesMovieContext(
                serviceProvider.GetRequiredService<
                    DbContextOptions<RazorPagesMovieContext>>()))
            {
                // Look for any movies.
                if (context.Movies.Any())
                {
                    return;   // DB has been seeded
                }

                context.Movies.AddRange(
                    new Movie
                    {
                        Title = "When Harry Met Sally",
                        ReleaseDate = DateTime.Parse("1989-2-12"),
                        Genre = "Romantic Comedy",
                        Price = 7.99M
                    },

                    new Movie
                    {
                        Title = "Ghostbusters ",
                        ReleaseDate = DateTime.Parse("1984-3-13"),
                        Genre = "Comedy",
                        Price = 8.99M
                    },

                    new Movie
                    {
                        Title = "Ghostbusters 2",
                        ReleaseDate = DateTime.Parse("1986-2-23"),
                        Genre = "Comedy",
                        Price = 9.99M
                    },

                    new Movie
                    {
                        Title = "Rio Bravo",
                        ReleaseDate = DateTime.Parse("1959-4-15"),
                        Genre = "Western",
                        Price = 3.99M
                    }
                );
                context.SaveChanges();
            }
        }
    }
}

ここは、自前でDbContextのインスタンスを生成しています。

これで、初期データをMoviesテーブルに挿入するクラスができました。テーブルが空でないなら何も行いません。

シード初期化コードの呼び出し

Program.cs で、次のように Main メソッドを変更します。

using Microsoft.Extensions.DependencyInjection;
using RazorPagesMovie.Models;



    public static void Main(string[] args)
    {
        var host = CreateHostBuilder(args).Build();

        using (var scope = host.Services.CreateScope())
        {
            var services = scope.ServiceProvider;

            try
            {
                SeedData.Initialize(services);
            }
            catch (Exception ex)
            {
                var logger = services.GetRequiredService<ILogger<Program>>();
                logger.LogError(ex, "An error occurred seeding the DB.");
            }
        }
        host.Run();
    }

実行してみる

では、動作するか確認してみます。

もし、データを登録してあったならば、https://localhost:5001/Movies ページに遷移し、Deleteリンクをクリックして、テーブル内のすべての行を削除してください。

それから、プログラムを停止し、再度アプリを起動します。これで、SeedData.Initializeメソッドが呼び出されて、初期データが挿入されるはずです。

スクリーンショット 2019-11-04 11.12.33.png

想定通り、SeedDataで挿入した初期データが表示されました。

appsettings.json

最後に、appsettings.jsonをのぞいてみます。

チュートリアルのappsettings.json を以下に示します。

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*",
  "ConnectionStrings": {
    "MovieContext": "Data Source=MvcMovie.db"
  }
}

"ConnectionStrings": が接続文字列を設定している個所です。

アプリ独自の設定も このファイルに書くことになるんでしょうね。ASP.NET MVC のweb.configの標準だと、

<add key="myKey" value="myValue" />

などと、設定情報を書いていたわけですが、json形式なので、柔軟性がかなり高くなっていそうです。

どうやってアプリケーション独自の設定値を読み込むのかは、また後で調べようと思います。

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2