Entity Framework Coreでデータベースを自動作成


99

.NETコアに移植されている私のアプリケーションは、SQLiteで新しいEFコアを使用します。アプリを最初に実行したときに、データベースとテーブルの構造を自動的に作成したいと思います。EFコアのドキュメントによると、これは手動コマンドを使用して行われます

dotnet ef migrations add MyFirstMigration

dotnet ef database update

ただし、エンドユーザーにこれらのコマンドを入力させたくないので、アプリでデータベースを作成してセットアップし、初めて使用することを望みます。EF 6の場合、次のような機能があります。

Database.SetInitializer(new CreateDatabaseIfNotExists<MyContext>());

しかし、EF Coreではこれらは存在しないようです。EFコアに相当するものの例やドキュメントが見つからないため、EFコアのドキュメントの不足している機能のリストに記載されていません。モデルクラスのセットアップは既に完了しているので、モデルに基づいてデータベースを初期化するコードを記述できますが、フレームワークがこれを自動的に実行すると、ヒープが簡単になります。モデルを自動構築したり移行したりするのではなく、新しいデータベースにテーブル構造を作成するだけです。

ここに何か不足していますか、それともEFコアにテーブル作成の自動作成機能が不足していますか?

回答:


146

マイグレーションを作成した場合、Startup.csで次のように実行できます。

 public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
 {
      using (var serviceScope = app.ApplicationServices.GetService<IServiceScopeFactory>().CreateScope())
      {
            var context = serviceScope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
            context.Database.Migrate();
      }

      ...

これにより、追加の移行を使用してデータベースとテーブルが作成されます。

Entity Framework Migrationsを使用せず、代わりに、DbContextモデルを最初の実行時にコンテキストクラスとまったく同じように作成する必要がある場合は、以下を使用できます。

 public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
 {
      using (var serviceScope = app.ApplicationServices.GetService<IServiceScopeFactory>().CreateScope())
      {
            var context = serviceScope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
            context.Database.EnsureCreated();
      }

      ...

代わりに。

データベースが作成されたことを確認する前にデータベースを削除する必要がある場合は、次を呼び出します。

            context.Database.EnsureDeleted();

電話する直前 EnsureCreated()

複製元:http : //docs.identityserver.io/en/latest/quickstarts/7_entity_framework.html?highlight=entity


1
私はまだEFの初心者ですが、現在のデータベースファイルを使用してVisual Studioから最初に「データベースから作成」するEF 6コードを使用して、データ構造を定義するクラスを作成しました。次に、これらを新しいドットネットコアVSソリューションに切り取り/貼り付けました。したがって、これらは移行ではないようです。上記のコードを使用するには、移行ファイルを作成する必要がありますか?
deandob 2017

2
申し訳ありませんが、回答を間違えました。移行を使用していない場合は、context.Database.EnsureCreated()/ EnsureDeleted()コマンドを使用できます。詳細については、blogs.msdn.microsoft.com
Ricardo Fontana

2
両方のソリューションが必要な場合はどうなりますか?アプリをUWPに移植してEF Coreの使用を開始しました。つまり、一部のユーザーはDBを最初から作成する必要がありますが、他のユーザーはすでにDBを持っています。最初の移行で最初のテーブルが存在しない場合にのみそれを作成するようにする方法はありますか?あなたの答えはこれをカバーしていないようです、または私は何かを逃していますか?
Lars Udengaard 2018

33

私の答えはリカルドの答えと非常によく似ていますが、彼のusing機能に多くのことが起こっているため、より低いレベルで正確に機能するかどうかさえわからないため、私のアプローチは少し単純です。

したがって、内部で何が行われているのかを正確に把握できるデータベースを作成するシンプルでクリーンなソリューションが必要な場合は、これが最適です。

public Startup(IHostingEnvironment env)
{
    using (var client = new TargetsContext())
    {
        client.Database.EnsureCreated();
    }
}

これはDbContext、作成した内(この場合はと呼ばれますTargetsContext)で、のインスタンスを使用して、アプリケーションでStartup.csを実行したDbContextときにクラスで定義されたテーブルが作成されることを確認できることを意味します。


10
以下からの情報と同じように、ここではEnsureCreated完全移行を迂回し、あなたのためだけにスキーマを作成するには、マイグレーションでこれを混在させることはできません。EnsureCreated毎回データベースを削除して再作成しても問題がないテストまたはラピッドプロトタイピング用に設計されています。移行を使用していて、アプリの起動時にそれらを自動的に適用したい場合は、context.Database.Migrate()代わりに使用できます。
Thomas Schneiter

これは、接続文字列が機能しない理由の混乱に答えます... :(データベースが自動的に作成されないため、DbContextコンストラクターで実行したDatabase.EnsureCreated()を指定する必要があります。ありがとうございました。3日間のジレンマから解放されます。 X_X
pampi

これをスタートアップファイルに貼り付けようとしたところ、VS2019から、IHostingEnvironment現在は非推奨であり、推奨される代替策はであることが通知されましたMicrosoft.AspNetCore.Hosting.IWebHostEnvironment
ctrl-z pls

18

Startup.csのConfigureのパラメーターリストを介してコンテキストを取得する場合は、代わりに次のように実行できます。

public void Configure(IApplicationBuilder app, IHostingEnvironment env,  LoggerFactory loggerFactory,
    ApplicationDbContext context)
 {
      context.Database.Migrate();
      ...

1
これが最善の解決策です。サービスやDBコンテキストさえ気にする必要はありません。依存関係の注入によって取得したコンテキストを使用できます。いいね!
トビアス

12

EF Core 2.0+の場合、APIが変更されたため、別のアプローチを取る必要がありました。2019年3月の時点で、Microsoftは、データベース移行コードをアプリケーションエントリクラスに配置することをお勧めしますが、WebHostビルドコードの外部に配置します。

public class Program
{
    public static void Main(string[] args)
    {
        var host = CreateWebHostBuilder(args).Build();
        using (var serviceScope = host.Services.CreateScope())
        {
            var context = serviceScope.ServiceProvider.GetRequiredService<PersonContext>();
            context.Database.Migrate();
        }
        host.Run();
    }

    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseStartup<Startup>();
}

7

マイグレーションを作成していない場合は、2つのオプションがあります

1.アプリケーションMainからデータベースとテーブルを作成します。

var context = services.GetRequiredService<YourRepository>();
context.Database.EnsureCreated();

2.データベースがすでに存在する場合は、テーブルを作成します。

var context = services.GetRequiredService<YourRepository>();
context.Database.EnsureCreated();
RelationalDatabaseCreator databaseCreator =
(RelationalDatabaseCreator)context.Database.GetService<IDatabaseCreator>();
databaseCreator.CreateTables();

ブビの答えに感謝


2
あなたのサービスは何ですか?
MichaelMao

私が読んでいるすべてのドキュメントには、「使用しないEnsureCreatedEnsureDeletedまたはDatabase.Migrate失敗する」という移行に関する
重大な
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.