Docker上で動かしたASP.NET Coreアプリで"no such table: テーブル名"となる場合の対処法
はじめに
ASP.NET Core + SQLiteで自作したアプリをDocker上で動かした際に"no such table:テーブル名"と出た際の対処方法を備忘録として記載します。
エラー内容
Dockerfileをビルドし、docker run ~ でコンテナを作成していざアクセスした時でした。
fail: Microsoft.EntityFrameworkCore.Database.Command[20102] Failed executing DbCommand (7ms) [Parameters=[], CommandType='Text', CommandTimeout='30'] SELECT "t"."TestId", "t"."CreatedTime", "t"."Number", "t"."Title", "t"."UpdatedTime", "t"."UserId" FROM "Tests" AS "t" fail: Microsoft.EntityFrameworkCore.Query[10100] An exception occurred while iterating over the results of a query for context type 'DDD.Domain.Data.TestMakerContext'. Microsoft.Data.Sqlite.SqliteException (0x80004005): SQLite Error 1: 'no such table: Tests'. at Microsoft.Data.Sqlite.SqliteException.ThrowExceptionForRC(Int32 rc, sqlite3 db) at Microsoft.Data.Sqlite.SqliteCommand.PrepareAndEnumerateStatements(Stopwatch timer)+MoveNext() at Microsoft.Data.Sqlite.SqliteCommand.GetStatements(Stopwatch timer)+MoveNext() at Microsoft.Data.Sqlite.SqliteDataReader.NextResult() at Microsoft.Data.Sqlite.SqliteCommand.ExecuteReader(CommandBehavior behavior) at Microsoft.Data.Sqlite.SqliteCommand.ExecuteDbDataReader(CommandBehavior behavior) at System.Data.Common.DbCommand.ExecuteReader() ・・・以下いっぱいのエラーログ
「Microsoft.Data.Sqlite.SqliteException (0x80004005): SQLite Error 1: 'no such table: Tests'.」とありますので、どうやら対象のテーブルができていないようです。
対処法
以下のstackoverflowにも記載されていますが、DbContextのコンストラクタへ「Database.EnsureCreated();」を追記するとテーブルが作成されるとのことでした。
ソースコードは以下のような感じになります。
public class TestMakerContext : DbContext { public TestMakerContext (DbContextOptions<TestMakerContext> options) : base(options) { Database.EnsureCreated(); // <-- 追記 } public DbSet<Test> Tests { get; set; } public DbSet<Question> Questions { get; set; } public DbSet<Choice> Choices { get; set; } public DbSet<User> Users { get; set; } }
Database.EnsureCreated()とは?
データベースが存在しない場合は、EnsureCreated によって作成され、データベーススキーマが初期化されます。 テーブルが存在する場合 (別の DbContext クラスのテーブルを含む)、スキーマは初期化されません。
データベースが存在しない場合に良い感じに作ってくれるみたいです。
デメリット
この記事を書くにあたり、色々と調べていたらどうやらこの方法だとデータベースの移行(Migrate)には対応しないようですね・・・(;´∀`)
移行を考慮している際は上記の記事によると「Database.Migrate ()」を使用することを推奨しているので、そちらもいずれ動作確認してみようと思います。