デザイン時 DbContext 作成

EF Core ツール コマンドの一部 (たとえば、移行 コマンド) では、アプリケーションのエンティティ型とデータベース スキーマへのそれらのマップ方法に関する詳細を収集するために、デザイン時に派生 DbContext インスタンスを作成する必要があります。 ほとんどの場合、それによって作成される DbContext は、実行時に構成される場合と同様の方法で構成されます。

ツールで DbContext を作成する方法には、さまざまなものがあります。

アプリケーション サービスから

スタートアップ プロジェクトで ASP.NET Core Web ホストまたは .NET Core 汎用ホストを使用している場合、ツールはアプリケーションのサービス プロバイダーから DbContext オブジェクトの取得を試みます。

ツールは最初に、Program.CreateHostBuilder() を起動し、Build() を呼び出し、次に Services プロパティにアクセスしてサービス プロバイダーの取得を試みます。

public class Program
{
    public static void Main(string[] args)
        => CreateHostBuilder(args).Build().Run();

    // EF Core uses this method at design time to access the DbContext
    public static IHostBuilder CreateHostBuilder(string[] args)
        => Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(
                webBuilder => webBuilder.UseStartup<Startup>());
}

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
        => services.AddDbContext<ApplicationDbContext>();

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
    }
}

public class ApplicationDbContext : DbContext
{
    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
        : base(options)
    {
    }
}

Note

新しい ASP.NET Core アプリケーションを作成すると、このフックが既定で含まれます。

DbContext 自体とそのコンストラクター内の依存関係は、アプリケーションのサービス プロバイダーにサービスとして登録する必要があります。 これは、DbContextOptions<TContext> のインスタンスを引数として受け取るコンストラクターを DbContext 上に用意し、AddDbContext<TContext> メソッドを使用することで簡単に実現できます。

パラメーターなしでコンストラクターを使用する

DbContext をアプリケーション サービス プロバイダーから取得できない場合、ツールはプロジェクト内で派生 DbContext 型を探します。 その後、パラメーターなしのコンストラクターを使用してインスタンスを作成しようとします。 DbContextOnConfiguring メソッドを使用して構成されている場合、これを既定のコンストラクターにすることができます。

デザイン時ファクトリから

Microsoft.EntityFrameworkCore.Design.IDesignTimeDbContextFactory<TContext> インターフェイスを実装して、DbContext の作成方法をツールに指示することもできます。このインターフェイスを実装するクラスが、派生 DbContext と同じプロジェクト内、またはアプリケーションのスタートアップ プロジェクト内で見つかった場合、ツールは DbContext を作成する他の方法を回避して、代わりにデザイン時ファクトリを使用します。

public class BloggingContextFactory : IDesignTimeDbContextFactory<BloggingContext>
{
    public BloggingContext CreateDbContext(string[] args)
    {
        var optionsBuilder = new DbContextOptionsBuilder<BloggingContext>();
        optionsBuilder.UseSqlite("Data Source=blog.db");

        return new BloggingContext(optionsBuilder.Options);
    }
}

デザイン時ファクトリが特に有用なのは、デザイン時に DbContext を実行時とは異なる方法で構成する必要がある場合、DbContext コンストラクターが DI に登録されていない追加のパラメーターを取る場合、DI をまったく使用していない場合、または何らかの理由で ASP.NET Core アプリケーションの Main クラスに CreateHostBuilder メソッドを置きたくない場合です。

引数

IDesignTimeDbContextFactory<TContext>.CreateDbContextProgram.CreateHostBuilder は、両方ともコマンド ライン引数を受け入れます。

これらの引数は、ツールから指定できます。

dotnet ef database update -- --environment Production

-- トークンは、後に続くすべてのものを引数として扱い、それらをオプションとして解析しないことを dotnet ef に指示します。 dotnet ef によって使用されない追加の引数はアプリに転送されます。