Comment configurez-vous DbContext lors de la création de migrations dans Entity Framework Core?

.net-core c# dbcontext dependency-injection entity-framework-core

Question

Existe-t-il un moyen de configurer / amorcer l’injection de dépendance lors de l’utilisation des commandes de migration d’Entity Framework?

Entity Framework Core prend en charge l'injection de dépendance pour les sous-classes DbContext . Ce mécanisme permet notamment de configurer l’accès aux données en dehors de DbContext .

Par exemple, les éléments suivants configurent EF pour qu'il persiste sur un serveur SQL à l'aide d'une chaîne de connexion extraite de config.json

ServiceCollection services = ...

var configuration = new Configuration().AddJsonFile( "config.json" );
services.AddEntityFramework( configuration )
    .AddSqlServer()
    .AddDbContext<BillingDbContext>( config => config.UseSqlServer() );

Cependant, les commandes de migration ne savent pas exécuter ce code, donc Add-Migration échouera faute de fournisseur ou de chaîne de connexion.

Les migrations peuvent fonctionner en OnConfiguring dans la sous-classe DbContext pour spécifier le fournisseur et la chaîne de configuration, mais cela DbContext le fait que différentes configurations soient souhaitées ailleurs. En fin de compte, garder les commandes de migration et mon code en train de fonctionner devient excessivement complexe.

Remarque: Mon DbContext réside dans un assemblage différent du point d'entrée qui l'utilise et ma solution comporte plusieurs projets de démarrage.

Réponse acceptée

Comme @bricelam a commenté cette fonctionnalité n'existe pas encore dans Entity Framework 7. Cette fonctionnalité manquante est suivie par le problème GitHub, aspnet / EntityFramework # 639.

Dans l’intervalle, la solution de contournement la plus simple que j’ai trouvée consistait à utiliser un état global plutôt que de s’embarrasser avec des sous-classes. Ce n’est généralement pas mon premier choix de conception, mais cela fonctionne bien pour le moment.

Dans MyDbContext:

public static bool isMigration = true;

protected override void OnConfiguring( DbContextOptionsBuilder optionsBuilder )
{
    // TODO: This is messy, but needed for migrations.
    // See https://github.com/aspnet/EntityFramework/issues/639
    if ( isMigration )
    {
        optionsBuilder.UseSqlServer( "<Your Connection String Here>" );
    }
}

Dans Startup.ConfigureServices() .

public IServiceProvider ConfigureServices( IServiceCollection services )
{
    MyContext.isMigration = false;

    var configuration = new Configuration().AddJsonFile( "config.json" );
    services.AddEntityFramework( configuration )
        .AddSqlServer()
        .AddDbContext<MyDbContext>( config => config.UseSqlServer() );
    // ...
}

(Le code de configuration réside actuellement dans un module Autofac dans mon cas.)


Réponse populaire

Utilisation de IDbContextFactory<TContext>

Implémentez cette interface pour activer les services au moment du design pour les types de contexte qui n'ont pas de constructeur par défaut public. Les services au moment du design découvriront automatiquement les implémentations de cette interface qui se trouvent dans le même assemblage que le contexte dérivé.

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

namespace MyProject
{
    public class BloggingContextFactory : IDbContextFactory<BloggingContext>
    {
        public BloggingContext Create()
        {
            var optionsBuilder = new DbContextOptionsBuilder<BloggingContext>();
            optionsBuilder.UseSqlServer("connection_string");

            return new BloggingContext(optionsBuilder.Options);
        }
    }
}

plus d'infos: https://docs.microsoft.com/en-us/ef/core/misc Miscellaneous / configuring - dbcontext

Si vous n'êtes pas satisfait de la chaîne de connexion codée en dur, consultez cet article.




Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi