113 votes

Impossible de créer des migrations après la mise à niveau vers ASP.NET Core 2.0

Après la mise à niveau vers ASP.NET Core 2.0, je ne parviens plus à créer des migrations.

Je reçois

"Une erreur s'est produite lors de l'appel de la méthode 'BuildWebHost' sur la classe Programme". Continuez sans le fournisseur de services d'application. Erreur : Une ou plusieurs erreurs se sont produites. (Impossible d'ouvrir la base de données "..." demandée par le l'ouverture de session. La connexion a échoué. La connexion a échoué pour l'utilisateur '...'".

y

"Impossible de créer un objet de type 'MyContext'. Ajoutez une implémentation de 'IDesignTimeDbContextFactory' au projet, ou voyez https://go.microsoft.com/fwlink/?linkid=851728 pour des motifs supplémentaires pris en charge au moment de la conception".

La commande que j'ai exécutée précédemment était $ dotnet ef migrations add InitialCreate --startup-project "..\Web" (à partir du projet/dossier contenant le DBContext).

Chaîne de connexion : "Server=(localdb)\\mssqllocaldb;Database=database;Trusted_Connection=True;MultipleActiveResultSets=true"

Voici mon Program.cs

 public class Program
{
    public static void Main(string[] args)
    {
        BuildWebHost(args).Run();
    }

    public static IWebHost BuildWebHost(string[] args) =>
       WebHost.CreateDefaultBuilder(args)
           .UseStartup<Startup>()
           .Build();
}

3 votes

Il est possible que le problème ne soit pas dans Program.cs. Il s'agit probablement de l'utilisation d'une instruction de chargement de données d'amorçage à la fin de votre méthode Configure : DbInitializer.Initialize(context) ; Si vous avez cette instruction, commentez-la : //DbInitializer.Initialize(context) ; Exécutez ensuite les instructions de migration pour les tester. Si le problème survient, suivez alors la classe DbInitializer.cs.

2 votes

Votre classe MyContext se trouve-t-elle dans un autre projet de bibliothèque de classes ?

0 votes

Même problème ici, le contexte est dans une autre bibliothèque. Si j'ajoute un consturcteur sans paramètre au contexte, les migrations fonctionnent, mais avec la même erreur : (Une erreur s'est produite lors de l'appel de la méthode 'BuildWebHost' sur la classe 'Program'. Continuer sans le fournisseur de service d'application. Erreur : Object reference not set to an instance of an object. )

129voto

jaaso Points 929

Vous pouvez ajouter une classe qui implémente IDesignTimeDbContextFactory à l'intérieur de votre projet Web.

Voici l'exemple de code :

public class DesignTimeDbContextFactory : IDesignTimeDbContextFactory<CodingBlastDbContext>
{
    public CodingBlastDbContext CreateDbContext(string[] args)
    {
        IConfigurationRoot configuration = new ConfigurationBuilder()
            .SetBasePath(Directory.GetCurrentDirectory())
            .AddJsonFile("appsettings.json")
            .Build();
        var builder = new DbContextOptionsBuilder<CodingBlastDbContext>();
        var connectionString = configuration.GetConnectionString("DefaultConnection");
        builder.UseSqlServer(connectionString);
        return new CodingBlastDbContext(builder.Options);
    }
}

Ensuite, naviguez dans votre projet de base de données et exécutez ce qui suit à partir de la ligne de commande :

dotnet ef migrations add InitialMigration -s ../Web/

dotnet ef database update -s ../Web/

-s stands for startup project and ../Web/ is the location of my web/startup project.

ressource

2 votes

J'obtiens : Le fichier de configuration 'appsettings.json' n'a pas été trouvé et n'est pas optionnel. Le chemin physique est ' C:\Users\XXX\Documents\Visual Studio 2017 \Projects\XXX\src\XXX.Api\bin\Debug\netcoreapp2.0\appset tings.json'. Mes appsettings sont dans C:\Users\XXX\Documents\Visual Studio 2017 \Projects\XXX\src\XXX.Api.

0 votes

Assurez-vous que le fichier appsettings.json est configuré pour copier le fichier local, ce qui devrait résoudre le problème de l'introuvabilité.

1 votes

Cette solution introduit une dépendance à Entity Framework dans votre application hôte (dans mon cas, il s'agit d'un projet Web). Existe-t-il un moyen de contourner ce problème ? Je voudrais que ma bibliothèque de référentiel contienne les éléments EF, et ne pas introduire EF dans l'application Web.

78voto

tchelidze Points 4891

Pas besoin de IDesignTimeDbContextFactory .

Exécuter

add-migration initial -verbose

qui révéler les détails sous

Une erreur s'est produite lors de l'accès à l'IWebHost de la classe 'Program'. Continuer sans le fournisseur de service d'application.

l'avertissement, qui est la Racine la cause du problème.

Dans mon cas le problème était que, ayant ApplicationRole : IdentityRole<int> et en invoquant services.AddIdentity<ApplicationUser, IdentityRole>() qui provoquait l'erreur suivante

System.ArgumentException: GenericArguments[1], 'Microsoft.AspNetCore.Identity.IdentityRole', 
on 'Microsoft.AspNetCore.Identity.EntityFrameworkCore.UserStore`9[TUser,TRole,TContext,
TKey,TUserClaim,TUserRole,TUserLogin,TUserToken,TRoleClaim]' violates the constraint of type 'TRole'.
---> System.TypeLoadException: GenericArguments[1], 'Microsoft.AspNetCore.Identity.IdentityRole', 
on 'Microsoft.AspNetCore.Identity.UserStoreBase`8[TUser,TRole,TKey,TUserClaim,
TUserRole,TUserLogin,TUserToken,TRoleClaim]' violates the constraint of type parameter 'TRole'.

0 votes

C'est bizarre, la commande add-migration initial a généré l'erreur no dbcontext found mais quand j'ai exécuté add-migration initial -verbose cela a fonctionné parfaitement. Je n'ai pas modifié le code, j'ai juste changé la commande. Vous savez pourquoi ?

0 votes

@OrthoHomeDefense bien, c'est vraiment bizarre. Je m'attends -verbose pour exposer les détails de l'erreur sous-jacente. Je ne sais pas vraiment pourquoi cela a corrigé une erreur.

3 votes

Oui -Verbose aide à découvrir le vrai problème. Dans mon cas, je n'ai pas ajouté les services AddDbContext au démarrage.

28voto

Ali Bayat Points 1331

Solution 1 : (Trouver le problème dans 99% des cas)

Définir Application web projet en tant que Projet de démarrage

Exécutez les commandes suivantes avec -verbose option.

Add-Migration Init -Verbose

-verbose Cette option permet de découvrir le vrai problème. contient des erreurs détaillées.

Solution 2 :

Renommer BuildWebHost() a CreateWebHostBuilder() parce que Entity Framework Core tools s'attendre à trouver un CreateHostBuilder qui configure l'hôte sans exécuter l'application.

.NET Core 2.2

public class Program
{
    public static void Main(string[] args)
    {
        CreateWebHostBuilder(args).Build().Run();
    }

    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseStartup<Startup>();
} 

.NET Core 3.1

Renommer BuildWebHost() a CreateHostBuilder()

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

Solution 3 :

Assurez-vous que vous avez ajouté Dbcontext à l'injection de dépendances : AddDbContext<TContext> rendra les deux types de votre DbContext, TContext et l'indice correspondant DbContextOptions<TContext> disponible pour l'injection à partir du conteneur de service. Cela nécessite d'ajouter un argument de constructeur à votre DbContext qui accepte DbContextOptions<TContext> .

Exemple : Dans Startup.cs

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<AppDbContext>(options => options.UseSqlServer(connectionString));
}

AppDbContext code :

public class AppDbContext: DbContext
{
    public AppDbContext(DbContextOptions<AppDbContext> options)
      :base(options)
    { }

}

1 votes

Cela a fonctionné pour moi. J'ai changé la fonction BuildWebHost dans Program.cs de public static IWebHostBuilder BuildWebHost(string[] args) a public static IWebHost BuildWebHost(string[] args) avec le .Build() maintenant inclus dans la fonction

2 votes

Les gars, si vous utilisez ASP.NET Core 2.1+, la méthode BuildWebHost portera un nom différent - CreateWebHostBuilder - en raison des éléments suivants docs.microsoft.com/fr/us/aspnet/core/migration/ Ainsi, renommez CreateWebHostBuilder en BuildWebHost et la migration trouvera BuildWebHost et prendra DbContext de celui-ci.

2 votes

Merci mec, résolu après avoir passé 2 heures à configurer sans utiliser IDesignTimeDbContextFactory

11voto

Dans mon cas, la cause du problème était de multiples projets de démarrage. J'ai trois projets dans ma solution : Mvc, Api, et Dal. DbContext et Migrations dans le projet Dal.

J'avais configuré plusieurs projets de démarrage. Les deux projets Mvc et Api s'exécutaient lorsque je cliquais sur Start. Mais dans ce cas, j'ai obtenu cette erreur.

"Impossible de créer un objet de type 'MyContext'. Ajoutez une implémentation de 'IDesignTimeDbContextFactory' au projet, ou voyez https://go.microsoft.com/fwlink/?linkid=851728 pour des motifs supplémentaires pris en charge au moment de la conception".

J'ai pu ajouter la migration avec succès après avoir défini Mvc comme le seul projet de démarrage et sélectionné Dal dans la console du gestionnaire de paquets.

1 votes

Merci, il m'est arrivé à peu près la même chose. J'ai dû changer le projet de démarrage à l'endroit où les classes Startup/Programmes existent. Le message d'erreur est une mauvaise blague.

1 votes

Les messages de sortie étaient vraiment frustrants. Je n'avais aucun projet de démarrage sélectionné, de manière inattendue. C'était la raison pour laquelle le dbContext ne pouvait pas être créé. Merci.

1 votes

Merci monsieur ... J'ai gagné beaucoup de temps.

8voto

Boris Points 55

Dans le fichier AppContext.cs, en plus de la classe AppContext, ajoutez une autre classe :

// required when local database deleted
public class ToDoContextFactory : IDesignTimeDbContextFactory<AppContext>
{
    public AppContext CreateDbContext(string[] args)
    {
        var builder = new DbContextOptionsBuilder<AppContext>();
          builder.UseSqlServer("Server=localhost;Database=DbName;Trusted_Connection=True;MultipleActiveResultSets=true");
        return new AppContext(builder.Options);
    }
}

Cela résoudra votre deuxième problème :

"Impossible de créer un objet de type 'MyContext'. Ajoutez une implémentation de 'IDesignTimeDbContextFactory' au projet,

Après cela, vous serez en mesure de add-migration Initial et l'exécuter en lançant update-database de la commande. Cependant, si vous exécutez ces commandes alors qu'il n'y a pas encore de base de données dans votre SqlServer local, vous obtiendrez un avertissement comme votre première erreur : "Une erreur

s'est produit lors de l'appel de la méthode 'BuildWebHost' sur la classe 'Program'... Le site connexion a échoué. La connexion a échoué pour l'utilisateur '...'"

Mais ce n'est pas une erreur car la migration sera créée et pourra être exécutée. Il suffit donc d'ignorer cette erreur pour la première fois, et plus tard, puisque la base de données existera, cela ne se reproduira plus.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X