Partage via


Création de DbContext au moment de la conception

Certaines des commandes EF Core Tools (par exemple, les commandes Migrations ) nécessitent la création d’une instance dérivée DbContext au moment du design afin de recueillir des détails sur les types d’entités de l’application et leur mappage à un schéma de base de données. Dans la plupart des cas, il est souhaitable que l'élément DbContext ainsi créé soit configuré de manière similaire à celle dont il serait configuré au moment de l’exécution.

Il existe différentes façons dont les outils essaient de créer le DbContext.

À partir des services d’application

Si votre projet de démarrage utilise l’hôte web ASP.NET Core ou l’hôte générique .NET Core, les outils tentent d’obtenir l’objet DbContext auprès du fournisseur de services de l’application.

Les outils essaient d’abord d’obtenir le fournisseur de services en appelant Program.CreateHostBuilder(), en appelant Build(), puis en accédant à la Services propriété.

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

Lorsque vous créez une application ASP.NET Core, ce hook est inclus par défaut.

DbContext lui-même et toutes les dépendances de son constructeur doivent être enregistrés comme services dans le fournisseur de services de l'application. Cela peut être facilement obtenu grâce à un constructeur sur le DbContext qui prend une instance de DbContextOptions<TContext> comme argument et en utilisant la méthode AddDbContext<TContext>.

Utilisation d’un constructeur sans paramètres

Si dbContext ne peut pas être obtenu à partir du fournisseur de services d’application, les outils recherchent le type dérivé DbContext à l’intérieur du projet. Ensuite, ils essaient de créer une instance à l’aide d’un constructeur sans paramètres. Il peut s’agir du constructeur par défaut si le DbContext est configuré par la méthode OnConfiguring.

À partir d’une fabrique au moment de la conception

Vous pouvez également indiquer aux outils comment créer votre DbContext en implémentant l’interface Microsoft.EntityFrameworkCore.Design.IDesignTimeDbContextFactory<TContext> : si une classe implémentant cette interface se trouve dans le même projet que le projet dérivé DbContext ou dans le projet de démarrage de l’application, les outils contournent les autres façons de créer dbContext et d’utiliser la fabrique au moment du design à la place.

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

Une fabrique au moment de la conception peut être particulièrement utile si vous devez configurer le DbContext différemment pour le moment de la conception par rapport au moment de l'exécution, si le constructeur DbContext accepte des paramètres supplémentaires qui ne sont pas enregistrés dans l'API d'injection de dépendances, si vous n’utilisez pas du tout l’injection de dépendances, ou si, pour une raison quelconque, vous préférez ne pas avoir de méthode CreateHostBuilder dans la classe Main de votre application ASP.NET Core.

Args

IDesignTimeDbContextFactory<TContext>.CreateDbContext et Program.CreateHostBuilder acceptent tous les deux les arguments de ligne de commande.

Vous pouvez spécifier ces arguments à partir des outils :

dotnet ef database update -- --environment Production

Le jeton -- dirige dotnet ef pour traiter tout ce qui suit comme argument, sans essayer de les analyser en tant qu’options. Tous les arguments supplémentaires, non utilisés par dotnet ef, sont transférés à l’application.