Creazione 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 provano a creare .DbContext Se viene trovato, IDesignTimeDbContextFactory<TContext> gli strumenti lo usano anziché gli altri modelli di creazione. Una factory in fase di progettazione è il modello consigliato per un progetto di migrazioni separato e per le applicazioni il cui progetto di avvio è specifico della piattaforma.

Dai servizi dell'applicazione

Se il progetto di avvio usa l'host Web principale 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)
    {
    }
}

Note

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

L'oggetto DbContext stesso e qualsiasi dipendenza nel relativo costruttore devono essere registrati come servizi nel fornitore 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 fabbrica 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 il costruttore di contesto presenta dipendenze che non sono registrate nell'inserimento delle dipendenze, se non si usa l'inserimento delle dipendenze o se il progetto di avvio dell'applicazione non può essere eseguito dagli strumenti.

Configurare lo stesso provider, le opzioni del modello e l'assembly delle migrazioni in fase di progettazione usato dall'applicazione in fase di esecuzione. In caso contrario, gli strumenti possono eseguire lo scaffolding delle migrazioni per un modello diverso dal modello usato dall'applicazione. Non presupporre che sia presente un argomento della riga di comando facoltativo; convalidare gli argomenti e fornire un'origine di configurazione o predefinita di sviluppo appropriata.

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.