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. Si une IDesignTimeDbContextFactory<TContext> valeur est trouvée, les outils l’utilisent au lieu des autres modèles de création. Une fabrique au moment de la conception est le modèle recommandé pour un projet de migrations distinct et pour les applications dont le projet de démarrage est spécifique à la plateforme.

À 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 du design peut être particulièrement utile si le constructeur de contexte a des dépendances qui ne sont pas inscrites dans l’id de domaine, si vous n’utilisez pas d’id de domaine ou si le projet de démarrage de l’application ne peut pas être exécuté par les outils.

Configurez le même fournisseur, les options de modèle et l’assembly de migrations au moment du design que l’application utilise au moment de l’exécution. Dans le cas contraire, les outils peuvent générer une structure des migrations pour un modèle qui diffère du modèle utilisé par l’application. Ne supposez pas qu’un argument de ligne de commande facultatif est présent ; validez les arguments et fournissez une source de développement ou de configuration appropriée.

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.