【ASP.NET Core 2.0】データベースのシードの作成方法
以下の記事の続きです。
データベースのシードとは
データベース初期化用のサンプルデータのことです。
アプリ起動時にデータベースにレコードが存在しない場合、自動でサンプルデータをインサートするプログラムを作成します。
公式のチュートリアルに沿って作成します。
[ Models ] を右クリックに SeedData クラス を追加します。
Program.csでアプリの起動時に呼びされます。
チュートリアルでは同期処理ですが、C#7.1以降では Main() メソッドを非同期に書けるので、非同期処理で作成します。
\models\seeddata.cs
using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; using System; using System.Threading.Tasks; namespace RazorPagesMovie.Models { public static class SeedData { public static async Task InitializeAsync(IServiceProvider serviceProvider) { using (var context = new MovieContext( serviceProvider.GetRequiredService<DbContextOptions<MovieContext>>())) { if (await context.Movie.AnyAsync()) { return; } await context.Movie.AddRangeAsync( new Movie { Title = "When Harry Met Sally", ReleaseDate = DateTime.Parse("1989-2-19"), 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 } ); await context.SaveChangesAsync(); } } } }
シード作成のメソッドは非同期処理の慣例に従って InitializeAsync とします。
context.Movie.AnyAsync() でデータベースにレコードが存在するかをチェックしすでにデータが存在する場合は登録を行いません。
AddRangeAsync() でMovie オブジェクトを追加します。
初期化はコレクション初期化子で行います。
Program.cs を上記で作成した SeedData.InitializeAsync を呼び出すように編集します。
using System; using System.Threading.Tasks; using Microsoft.AspNetCore; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using RazorPagesMovie.Models; using Microsoft.EntityFrameworkCore; namespace RazorPagesMovie { public class Program { public static async Task Main(string[] args) { IWebHost host = BuildWebHost(args); using (IServiceScope scorp = host.Services.CreateScope()) { IServiceProvider services = scorp.ServiceProvider; try { MovieContext context = services.GetRequiredService<MovieContext>(); await context.Database.MigrateAsync(); await SeedData.InitializeAsync(services); } catch (Exception ex) { ILogger<Program> logger = services.GetRequiredService<ILogger<Program>>(); logger.LogError(ex, "An error occurred seeding the DB."); } } await host.RunAsync(); } public static IWebHost BuildWebHost(string[] args) => WebHost.CreateDefaultBuilder(args) .UseStartup<Startup>() .Build(); } }
C# 7.0以下の場合には上記の Main() メソッド内を格納した MainAsync() メソッドを作成し、Main() メソッドから以下のように呼び出します。
public static void Main(string[] args) { MainAsync(args).GetAwaiter().GetResult(); }
データベースのレコードすべて削除します。
アプリを起動し削除ページからすべてのデータを削除するか、SQL Server Object Explorer からデータベースを削除してパッケージマネージャーコンソールで Update-Database します。
アプリを起動すると以下のようにシードデータが表示されます。