ASP.NET Core 3.0 Razor Pages 事始め(5)の続きです。
今回は、公式チュートリアルのデータベースと 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
のインスタンスを受け取っています。
publicclassIndexModel:PageModel{privatereadonlyRazorPagesMovie.Models.RazorPagesMovieContext_context;publicIndexModel(RazorPagesMovie.Models.RazorPagesMovieContextcontext){_context=context;}……
チュートリアルのページによると、
テストサーバーまたは運用サーバーにデプロイされると、環境変数を使用して接続文字列を実際のデータベース サーバーに設定できます。
とのことです。この辺りは、ASP.NET MVC5とは異なりますね。
具体的にどうやるのか調べたいところですが、前回、前々回のように脇道にそれていると、なかなか進まないので、必要になった時に、このあたりも調べようと思います。
データベースのシード
初期データをインサートする処理を作成します。そのため、Modelsフォルダに、SeedData
という名前のクラスを新規作成します。
SeedData
クラスのコードは以下のとおりです。
usingMicrosoft.EntityFrameworkCore;usingMicrosoft.Extensions.DependencyInjection;usingSystem;usingSystem.Linq;usingRazorPagesMovie.Data;namespaceRazorPagesMovie.Models{publicstaticclassSeedData{publicstaticvoidInitialize(IServiceProviderserviceProvider){using(varcontext=newRazorPagesMovieContext(serviceProvider.GetRequiredService<DbContextOptions<RazorPagesMovieContext>>())){// Look for any movies.if(context.Movies.Any()){return;// DB has been seeded}context.Movies.AddRange(newMovie{Title="When Harry Met Sally",ReleaseDate=DateTime.Parse("1989-2-12"),Genre="Romantic Comedy",Price=7.99M},newMovie{Title="Ghostbusters ",ReleaseDate=DateTime.Parse("1984-3-13"),Genre="Comedy",Price=8.99M},newMovie{Title="Ghostbusters 2",ReleaseDate=DateTime.Parse("1986-2-23"),Genre="Comedy",Price=9.99M},newMovie{Title="Rio Bravo",ReleaseDate=DateTime.Parse("1959-4-15"),Genre="Western",Price=3.99M});context.SaveChanges();}}}}
ここは、自前でDbContextのインスタンスを生成しています。
これで、初期データをMoviesテーブルに挿入するクラスができました。テーブルが空でないなら何も行いません。
シード初期化コードの呼び出し
Program.cs
で、次のように Main
メソッドを変更します。
usingMicrosoft.Extensions.DependencyInjection;usingRazorPagesMovie.Models;…publicstaticvoidMain(string[]args){varhost=CreateHostBuilder(args).Build();using(varscope=host.Services.CreateScope()){varservices=scope.ServiceProvider;try{SeedData.Initialize(services);}catch(Exceptionex){varlogger=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の標準だと、
<addkey="myKey"value="myValue"/>
などと、設定情報を書いていたわけですが、json形式なので、柔軟性がかなり高くなっていそうです。
どうやってアプリケーション独自の設定値を読み込むのかは、また後で調べようと思います。