記事目次
- ASP.NET Core 3.0 Razor Pages 事始め(1) - はじめてのRazor Pagesアプリケーション
- ASP.NET Core 3.0 Razor Pages 事始め(2) - スキャフォールディングとDBマイグレーション
- ASP.NET Core 3.0 Razor Pages 事始め(3) - マイグレーションのやり直しとURLルーティング
- ASP.NET Core 3.0 Razor Pages 事始め(4) - ページモデルとページハンドラ
- ASP.NET Core 3.0 Razor Pages 事始め(5) - Postページハンドラとタグヘルパー
- ASP.NET Core 3.0 Razor Pages 事始め(6) - データベースに初期値を設定する <-- この記事
- ASP.NET Core 3.0 Razor Pages 事始め(7) - Viewの変更とコンカレンシー例外処理
- ASP.NET Core 3.0 Razor Pages 事始め(8) - 検索機能の追加
- ASP.NET Core 3.0 Razor Pages 事始め(9) - ページに新しいフィールドを追加する
- 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
メソッドが呼び出されて、初期データが挿入されるはずです。
想定通り、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形式なので、柔軟性がかなり高くなっていそうです。
どうやってアプリケーション独自の設定値を読み込むのかは、また後で調べようと思います。