web-dev-qa-db-ja.com

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

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

dotnet ef migrations add MyFirstMigration

dotnet ef database update

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

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

しかしEFコアではこれらは存在しないようです。 EFコアと同等のものに関する例やドキュメントは見つかりません。また、EFコアのドキュメントの欠けている機能のリストには記載されていません。モデルクラスはすでに設定されているので、モデルに基づいてデータベースを初期化するためのコードを書くことができますが、フレームワークがこれを自動的に行った方が簡単です。モデルの自動構築や移行はしたくありません。新しいデータベースにテーブル構造を作成するだけです。

ここに何か足りないのでしょうか、それともEFコアに自動テーブル作成機能がないのでしょうか。

61
deandob

移行を作成した場合は、次のように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/release/quickstarts/8_entity_framework.html?highlight=entity

87
Ricardo Fontana

私の答えはRicardoの答えと非常によく似ていますが、彼のusing関数で行われていることが多すぎるため、私のアプローチはもう少し分かりやすいと感じています。

だから、フードの下で何が起こっているのかを正確に知っている、あなたのためにデータベースを作成するシンプルでクリーンなソリューションを望んでいる人々のために、これはあなたのためです:

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

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

24
susieloo_

Startup.csのConfigureのパラメータリストからコンテキストを取得する場合は、代わりにこれを実行できます。

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

移行を作成していない場合は、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();

Bubiのおかげで 答え

6
Nathan Alard

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>();
}
1
Paul Stegler