Creazione di DbContext in fase di progettazione

Alcuni dei comandi di EF Core Tools (ad esempio, i comandi Migrations ) richiedono la creazione di un'istanza derivata DbContext in fase di progettazione per raccogliere informazioni dettagliate sui tipi di entità dell'applicazione e su come eseguono il mapping a uno schema di database. Nella maggior parte dei casi, è consigliabile configurare l'oggetto DbContext creato in modo analogo alla modalità di configurazione in fase di esecuzione.

Esistono diversi modi in cui gli strumenti tentano di creare :DbContext

Dai servizi dell'applicazione

Se il progetto di avvio usa l'host Web principale di ASP.NET o l'host generico .NET Core, gli strumenti tentano di ottenere l'oggetto DbContext dal provider di servizi dell'applicazione.

Gli strumenti tentano prima di tutto di ottenere il provider di servizi richiamando Program.CreateHostBuilder(), chiamando Build(), quindi accedendo alla Services proprietà .

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)
    {
    }
}

Nota

Quando si crea una nuova applicazione ASP.NET Core, questo hook viene incluso per impostazione predefinita.

L'oggetto DbContext stesso e le eventuali dipendenze nel relativo costruttore devono essere registrati come servizi nel provider di servizi dell'applicazione. Questa operazione può essere ottenuta facilmente con un costruttore in DbContext che accetta un'istanza di DbContextOptions<TContext> come argomento e usando il AddDbContext<TContext> metodo .

Uso di un costruttore senza parametri

Se il dbContext non può essere ottenuto dal provider di servizi dell'applicazione, gli strumenti cercano il tipo derivato DbContext all'interno del progetto. Quindi provano a creare un'istanza usando un costruttore senza parametri. Può trattarsi del costruttore predefinito se DbContext è configurato usando il OnConfiguring metodo .

Da una factory in fase di progettazione

È anche possibile indicare agli strumenti come creare DbContext implementando l'interfaccia Microsoft.EntityFrameworkCore.Design.IDesignTimeDbContextFactory<TContext> : se una classe che implementa questa interfaccia si trova nello stesso progetto del progetto derivato DbContext o nel progetto di avvio dell'applicazione, gli strumenti ignorano gli altri modi per creare DbContext e usare invece la factory in fase di progettazione.

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);
    }
}

Una factory in fase di progettazione può essere particolarmente utile se è necessario configurare in modo diverso per la DbContext fase di progettazione rispetto a quella in fase di esecuzione, se il DbContext costruttore accetta parametri aggiuntivi non sono registrati nell'inserimento delle dipendenze, se non si usa affatto l'inserimento delle dipendenze o se per qualche motivo si preferisce non disporre di un CreateHostBuilder metodo nella classe dell'applicazione Main ASP.NET Core.

Args

Entrambi IDesignTimeDbContextFactory<TContext>.CreateDbContext e Program.CreateHostBuilder accettano gli argomenti della riga di comando.

È possibile specificare questi argomenti dagli strumenti:

dotnet ef database update -- --environment Production

Il -- token indirizza dotnet ef a trattare tutto ciò che segue come argomento e non cerca di analizzarli come opzioni. Eventuali argomenti aggiuntivi non usati da dotnet ef vengono inoltrati all'app.