Creazione DbContext della fase di progettazioneDesign-time DbContext Creation

Alcuni dei comandi degli strumenti di EF Core (ad esempio, i comandi delle migrazioni ) richiedono la DbContext creazione di un'istanza derivata in fase di progettazione per raccogliere informazioni dettagliate sui tipi di entità dell'applicazione e su come eseguono il mapping a uno schema del database.Some of the EF Core Tools commands (for example, the Migrations commands) require a derived DbContext instance to be created at design time in order to gather details about the application's entity types and how they map to a database schema. Nella maggior parte dei casi, è preferibile che il DbContext creato sia configurato in modo analogo a come verrebbe configuratoin fase di esecuzione.In most cases, it is desirable that the DbContext thereby created is configured in a similar way to how it would be configured at run time.

Esistono diversi modi in cui gli strumenti tentano di DbContextcreare:There are various ways the tools try to create the DbContext:

Da servizi applicazioniFrom application services

Se il progetto di avvio usa il ASP.NET Core host Web o l' host generico .NET Core, gli strumenti tentano di ottenere l'oggetto DbContext dal provider di servizi dell'applicazione.If your startup project uses the ASP.NET Core Web Host or .NET Core Generic Host, the tools try to obtain the DbContext object from the application's service provider.

Per prima cosa gli strumenti tentano di ottenere il provider di Program.CreateHostBuilder()Servizi richiamando Build(), quindi accedendo alla Services proprietà.The tools first try to obtain the service provider by invoking Program.CreateHostBuilder(), calling Build(), then accessing the Services property.

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 class ApplicationDbContext : DbContext
{
    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
        : base(options)
    {
    }
}

Nota

Quando si crea una nuova applicazione ASP.NET Core, questo hook è incluso per impostazione predefinita.When you create a new ASP.NET Core application, this hook is included by default.

La DbContext stessa e tutte le dipendenze nel costruttore devono essere registrate come servizi nel provider di servizi dell'applicazione.The DbContext itself and any dependencies in its constructor need to be registered as services in the application's service provider. Questa operazione può essere eseguita facilmente con un DbContext Costruttore su che accetta un'istanza di DbContextOptions<TContext> come argomento e usando il AddDbContext<TContext> metodo.This can be easily achieved by having a constructor on the DbContext that takes an instance of DbContextOptions<TContext> as an argument and using the AddDbContext<TContext> method.

Uso di un costruttore senza parametriUsing a constructor with no parameters

Se il DbContext non può essere ottenuto dal provider di servizi dell'applicazione, gli strumenti cercano il DbContext tipo derivato all'interno del progetto.If the DbContext can't be obtained from the application service provider, the tools look for the derived DbContext type inside the project. Tentano quindi di creare un'istanza usando un costruttore senza parametri.Then they try to create an instance using a constructor with no parameters. Può essere il costruttore predefinito se DbContext è configurato utilizzando il OnConfiguring metodo.This can be the default constructor if the DbContext is configured using the OnConfiguring method.

Da una factory della fase di progettazioneFrom a design-time factory

È anche possibile indicare agli strumenti come creare il DbContext implementando l' IDesignTimeDbContextFactory<TContext> interfaccia: Se una classe che implementa questa interfaccia si trova nello stesso progetto dell'oggetto derivato DbContext o nel progetto di avvio dell'applicazione, gli strumenti ignorano le altre modalità di creazione di DbContext e usano invece la factory della fase di progettazione.You can also tell the tools how to create your DbContext by implementing the IDesignTimeDbContextFactory<TContext> interface: If a class implementing this interface is found in either the same project as the derived DbContext or in the application's startup project, the tools bypass the other ways of creating the DbContext and use the design-time factory instead.

using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Design;
using Microsoft.EntityFrameworkCore.Infrastructure;

namespace MyProject
{
    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);
        }
    }
}

Nota

Il args parametro non è attualmente utilizzato.The args parameter is currently unused. Si è verificato un problema durante il rilevamento della possibilità di specificare gli argomenti della fase di progettazione dagli strumenti.There is an issue tracking the ability to specify design-time arguments from the tools.

Una factory della fase di progettazione può essere particolarmente utile se è necessario configurare DbContext in modo diverso per la fase di progettazione rispetto al runtime, DbContext se il costruttore accetta parametri aggiuntivi non viene registrato in di, se non si utilizza o se per alcuni motivo per cui si preferisce non avere BuildWebHost un metodo nella Main classe dell'applicazione ASP.NET Core.A design-time factory can be especially useful if you need to configure the DbContext differently for design time than at run time, if the DbContext constructor takes additional parameters are not registered in DI, if you are not using DI at all, or if for some reason you prefer not to have a BuildWebHost method in your ASP.NET Core application's Main class.