Quantcast
Channel: C#タグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 9703

Entity Framework Core の In-Memory データベースに初期データを投入する

$
0
0

はじめに

テストや環境を汚さないために In-Memory データベースを使用する際に初期データを投入する方法を調べました。

データベースコンテキストのOnModelCreatingメソッドにフックすることで初期化します。
OnModelCreatingはデータベースコンテキストが初期化される際に1度だけ呼ばれます。

HasDataメソッドの初期化は、Entity Framework CoreによるIDの自動設定 が行われません。
そのため、自分でIDを取得する必要があります。

publicDbSet<Book>Books{get;set;}protectedoverridevoidOnModelCreating(ModelBuildermodelBuilder)=>modelBuilder.Entity<Book>().HasData(newBook{ID=1,Name="アンドロイドは電気羊の夢を見るか?"},newBook{ID=2,Name="幼年期の終り"},newBook{ID=3,Name="一九八四年"});

サンプルアプリ In-Memory データベース を使った Web API

プロジェクトの雛形の作成

# テンプレートには Web API を選択$ dotnet new webapi -n SeedingInMemoryDb
$ cd SeedingInMemoryDb
# In-Memory データベースを使うためにライブラリをインストール$ dotnet add Package Microsoft.EntityFrameworkCore.InMemory

モデルとデータベースコンテキスト

Models/Books.cs
publicclassBook{publicintID{get;set;}publicstringName{get;set;}}
// using Microsoft.EntityFrameworkCore;// using SeedingInMemoryDb.Models;publicclassSampleInMemoryDbContext:DbContext{publicSampleInMemoryDbContext(DbContextOptionsoptions):base(options){}publicDbSet<Book>Books{get;set;}protectedoverridevoidOnModelCreating(ModelBuildermodelBuilder)=>modelBuilder.Entity<Book>().HasData(newBook{ID=1,Name="アンドロイドは電気羊の夢を見るか?"},newBook{ID=2,Name="幼年期の終り"},newBook{ID=3,Name="一九八四年"});}

Startupクラス

In-Memory データベースを使う設定をします。
いつも通りAddDbContextする際にオプションからUseInMemoryDatabaseメソッドを呼びます。
UseInMemoryDatabaseメソッドの引数のデータベース名は必須みたいです。

Startup.cs
// using Microsoft.EntityFrameworkCore;// using Microsoft.Extensions.DependencyInjection;publicvoidConfigureServices(IServiceCollectionservices){services.AddDbContext<SampleInMemoryDbContext>(options=>options.UseInMemoryDatabase("sample_in_memory_db"););services.AddControllers();}

エントリーポイント

In-Memory データベースを構築し初期データを投入します。

Program.csではまだ DI コンテナが設定前であるため、データベースコンテキストを DI できません。
サービスプロバイダーからインスタンスを取得しEnsureCreatedAsyncメソッドを呼んで DB を作成します。

Program.cs
// using Microsoft.AspNetCore.Hosting;// using Microsoft.Extensions.DependencyInjection;// using Microsoft.Extensions.Hosting;// using System.Threading.Tasks;publicclassProgram{publicstaticasyncTaskMain(string[]args){IHosthost=BuildHost(args);usingIServiceScopescope=host.Services.CreateScope();IServiceProviderprovider=scope.ServiceProvider;usingvarcontext=provider.GetRequiredService<SampleInMemoryDbContext>();awaitcontext.Database.EnsureCreatedAsync();host.Run();}publicstaticIHostBuildHost(string[]args)=>Host.CreateDefaultBuilder(args).ConfigureWebHostDefaults(web=>web.UseStartup<Startup>().Build();}

コントローラークラス

In-Memory データベース内の書籍を全件返すエンドポイント/api/booksを作ってみます。

Controllers/BooksController.cs
// using Microsoft.AspNetCore.Mvc;// using Microsoft.EntityFrameworkCore;// using SeedingInMemoryDb.Models;// using System.Collections.Generic;// using System.Threading.Tasks;[Route("api/[controller]")]publicclassBooksController:Controller{privatereadonlySampleInMemoryDbContext_db;publicBooksController(SampleInMemoryDbContextdb)=>_db=db;[HttpGet]publicasyncTask<ActionResult<IEnumerable<Book>>>Get()=>await_db.Books.ToListAsync();}

実行結果

実行しlocalhost:{ポート番号}/api/booksにアクセスします。
In-Memory データベースに初期データが投入され、そのデータを全件取得できることが確認できました。
image.png

実行環境は以下の通りです。

  • Windows X64
  • Visual Studio 2019 (v16.4)
  • .NET Core SDK 3.1.101
  • C# 8.0

Viewing all articles
Browse latest Browse all 9703

Trending Articles