デザイン時 DbContext 作成

一部の EF Core Tools コマンド ( Migrations コマンドなど) では、アプリケーションのエンティティ型とデータベース スキーマへのマップ方法に関する詳細を収集するために、設計時に派生 DbContext インスタンスを作成する必要があります。 ほとんどの場合、作成される DbContext は、実行時の構成方法と同様の方法 で構成することをお勧めします。

ツールが DbContextを作成しようとするさまざまな方法があります。 IDesignTimeDbContextFactory<TContext>が見つかった場合、ツールは他の作成パターンの代わりにそれを使用します。 設計時ファクトリは、 個別の移行プロジェクト と、スタートアップ プロジェクトがプラットフォーム固有のアプリケーションに推奨されるパターンです。

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

スタートアップ プロジェクトで 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自体とそのコンストラクター内の依存関係は、アプリケーションのサービス プロバイダーにサービスとして登録する必要があります。 これは、DbContextのインスタンスを引数として受け取るDbContextOptions<TContext>にコンストラクターを持ち、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);
    }
}

デザイン時ファクトリは、コンテキスト コンストラクターに DI に登録されていない依存関係がある場合、DI を使用していない場合、またはアプリケーションスタートアップ プロジェクトをツールで実行できない場合に特に便利です。

アプリケーションが実行時に使用するのと同じプロバイダー、モデル オプション、および移行アセンブリを設計時に構成します。 それ以外の場合、ツールは、アプリケーションで使用されるモデルとは異なるモデルの移行をスキャフォールディングできます。 省略可能なコマンド ライン引数が存在することを想定しないでください。引数を検証し、適切な開発の既定値または構成ソースを指定します。

Args

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

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

dotnet ef database update -- --environment Production

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