了解です。では、さらに構成を変えて、
「アプリ起動時に非同期で初期データを投入する」 サンプルにリファクタリングします。
これにより、大量データや外部API連携を伴う初期化にも対応しやすくなります。
① DbContext クラス
using Microsoft.EntityFrameworkCore;
public class AppDbContext : DbContext
{
public DbSet<User> Users { get; set; }
public AppDbContext(DbContextOptions<AppDbContext> options)
: base(options) { }
}
② モデルクラス
public class User
{
public int Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
}
③ 非同期初期化クラス
public static class DatabaseInitializer
{
public static async Task SeedAsync(AppDbContext db)
{
// 既にデータがある場合はスキップ
if (await db.Users.AnyAsync()) return;
var initialUsers = new List<User>
{
new User { Name = "Admin", Email = "admin@example.com" },
new User { Name = "Guest", Email = "guest@example.com" }
};
await db.Users.AddRangeAsync(initialUsers);
await db.SaveChangesAsync();
}
}
④ Program.cs(ASP.NET Core MVC の場合)
var builder = WebApplication.CreateBuilder(args);
// DbContext 登録
builder.Services.AddDbContext<AppDbContext>(options =>
options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));
var app = builder.Build();
// 起動時に DB 作成&非同期初期化
using (var scope = app.Services.CreateScope())
{
var db = scope.ServiceProvider.GetRequiredService<AppDbContext>();
await db.Database.MigrateAsync();
await DatabaseInitializer.SeedAsync(db);
}
app.MapDefaultControllerRoute();
await app.RunAsync();
⑤ 接続文字列例(appsettings.json)
{
"ConnectionStrings": {
"DefaultConnection": "Server=localhost;Database=MyAppDb;Trusted_Connection=True;TrustServerCertificate=True;"
}
}
この非同期版のメリット
- 大量データ投入時でも UI スレッドをブロックしない。
- 外部APIやファイル読み込みを伴う初期化処理を組み込みやすい。
- 将来的にクラウドDBやリモート接続でも安定動作。
この非同期パターンは、特に クラウド環境やコンテナ起動時の初期化 に向いています。
もし希望があれば、このコードを .NET Framework MVC 用に同期処理へ変換したバージョン も作成できます。
もしよければ、この非同期版に トランザクション管理 を組み込んだ安全性の高いバージョンもお見せできますが、そちらにしますか?