Unable to create migrations after upgrading to ASP.NET Core 2.0

123,290

Solution 1

You can add a class that implements IDesignTimeDbContextFactory inside of your Web project.

Here is the sample 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);
    }
}

Then, navigate to your Database project and run the following from command line:

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.

resource

Solution 2

No need for IDesignTimeDbContextFactory.

Run

add-migration initial -verbose

that will reveal the details under

An error occurred while accessing the IWebHost on class 'Program'. Continuing without the application service provider.

warning, which is the root cause of the problem.

In my case, problem was, having ApplicationRole : IdentityRole<int> and invoking services.AddIdentity<ApplicationUser, IdentityRole>() which was causing below error

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'.

Solution 3

Solution 1: (Find the problem in 99% of cases)

Set Web Application project as Startup Project

Run the following commands with -verbose option.

Add-Migration Init -Verbose

-verbose option helps to actually uncover the real problem, It contains detailed errors.

Solution 2:

Rename BuildWebHost() to CreateWebHostBuilder(), because Entity Framework Core tools expect to find a CreateHostBuilder method that configures the host without running the app.

.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

Rename BuildWebHost() to 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:

Make sure you added Dbcontext to dependency injection: AddDbContext<TContext> will make both your DbContext type, TContext, and the corresponding DbContextOptions<TContext> available for injection from the service container. This requires adding a constructor argument to your DbContext type that accepts DbContextOptions<TContext>.

Example: In 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)
    { }

}

Solution 4

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

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

Just rename BuildWebHost() to CreateWebHostBuilder(), because migrations use this method by default.

Solution 5

In my case, the cause of the problem was multiple startup projects. I have three projects in my solution: Mvc, Api, and Dal. DbContext and Migrations in the Dal project.

I had configured multiple startup projects. Both Mvc and Api projects were running when I clicked Start. But in this case I was getting this error.

"Unable to create an object of type 'MyContext'. Add an implementation of 'IDesignTimeDbContextFactory' to the project, or see https://go.microsoft.com/fwlink/?linkid=851728 for additional patterns supported at design time."

I could successfully add migration after setting Mvc as the only startup project and selecting Dal in the Package Manager Console.

Share:
123,290

Related videos on Youtube

ruhm
Author by

ruhm

Updated on January 28, 2021

Comments

  • ruhm
    ruhm over 3 years

    After upgrading to ASP.NET Core 2.0, I can't seem to create migrations anymore.

    I'm getting

    "An error occurred while calling method 'BuildWebHost' on class 'Program'. Continuing without the application service provider. Error: One or more errors occurred. (Cannot open database "..." requested by the login. The login failed. Login failed for user '...'"

    and

    "Unable to create an object of type 'MyContext'. Add an implementation of 'IDesignTimeDbContextFactory' to the project, or see https://go.microsoft.com/fwlink/?linkid=851728 for additional patterns supported at design time."

    The command I previously ran was $ dotnet ef migrations add InitialCreate --startup-project "..\Web" (from the project/folder with the DBContext).

    Connection string: "Server=(localdb)\\mssqllocaldb;Database=database;Trusted_Connection=True;MultipleActiveResultSets=true"

    This is my 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();
    }
    
    • Miguel Torres C
      Miguel Torres C over 6 years
      Possibly the problem is not in Program.cs. It is probably the use of an instruction to load seed data at the end of your Configure method: DbInitializer.Initialize (context); If you have that instruction, comment it: //DbInitializer.Initialize(context); Then run the Migration instructions to test. If the problem arises, then follow up on the DbInitializer.cs class.
    • Orhun
      Orhun over 6 years
      Is your MyContext class in another class library project?
    • iBoonZ
      iBoonZ over 6 years
      Same issue here, context is in other library. If id add an parameter less consturctor to the context, migrations are working, but with the same error: (An error occurred while calling method 'BuildWebHost' on class 'Program'. Continuing without the application service provider. Error: Object reference not set to an instance of an object. )
    • Konrad Viltersten
      Konrad Viltersten over 6 years
      Did you get it resolved in the end?
    • Amit Philips
      Amit Philips almost 6 years
      @MiguelTorresC thanks for that comment. I commented out my Seeding Methods and Migrations began to work again. Thanks a ton !!!
    • Darleison Rodrigues
      Darleison Rodrigues over 5 years
      Check in Startup.cs if there a line with service.DbContext<YourContext>. If not add and try to make a migration.
  • ruhm
    ruhm over 6 years
    I'm using <PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0" /> which includes that reference. I tried also including the above, but no change.
  • Reft
    Reft over 6 years
    I'm getting: The configuration file 'appsettings.json' was not found and is not optional. The physical path is 'C:\Users\XXX\Documents\Visual Studio 2017\Projects\XXX\src\XXX.Api\bin\Debug\netcoreapp2.0\appset‌​tings.json'. My appsettings is in C:\Users\XXX\Documents\Visual Studio 2017\Projects\XXX\src\XXX.Api.
  • Reft
    Reft over 6 years
    I'm still getting: Add an implementation of 'IDesignTimeDbContextFactory<DatabaseContext>'......
  • Serg
    Serg over 6 years
    Thanks, this helped me too.
  • DaImTo
    DaImTo over 6 years
    Make sure you have the appsettings.json file set to copy local should fix the issue with it not being found
  • hellow
    hellow over 5 years
    While this might answer the authors question, it lacks some explaining words and links to documentation. Raw code snippets are not very helpful without some phrases around it. You may also find how to write a good answer very helpful. Please edit your answer.
  • Train
    Train over 5 years
    This is weird, the command add-migration initial threw the error no dbcontext found but when I ran add-migration initial -verbose it worked perfectly. I didn't make any code changes just changed the command. Any idea why?
  • tchelidze
    tchelidze over 5 years
    @OrthoHomeDefense well, that's really weird. I expect -verbose to expose the underlying error details. Not really sure why it fixed an error.
  • Banoona
    Banoona over 5 years
    This solution introduces a dependency on Entity Framework into your host application (in my case this is a Web project). Is there any way to get around this? I would like my Repository library to hold the EF stuff, and not introduce EF into the web app.
  • sudhakarssd
    sudhakarssd over 5 years
    Yes -Verbose helps to actually uncover the real problem. In my case haven't added AddDbContext services to startup.
  • Jon Koivula
    Jon Koivula about 5 years
    Hmm for me add-migration initial worked. How come it worked while using dotnet ef migrations add initial did not?
  • zola25
    zola25 about 5 years
    This worked for me. Changed the BuildWebHost function in Program.cs from public static IWebHostBuilder BuildWebHost(string[] args) to public static IWebHost BuildWebHost(string[] args) with the .Build() now included in the function
  • barbara.post
    barbara.post about 5 years
    dotnet ef migrations add InitialCreate --verbose
  • barbara.post
    barbara.post about 5 years
    Despite this is the accepted answer, this one is better: stackoverflow.com/a/52671330/1737395 Indeed, running the migration with --verbose flag helps greatly
  • Tiago Ávila
    Tiago Ávila about 5 years
    @tchelidze Thank you for that, in my case I didn't have a parameterless constructor in my ApplicationDbContext.
  • KEMBL
    KEMBL almost 5 years
    Guys, if you are using ASP.NET Core 2.1+ you BuildWebHost method will have a different name - CreateWebHostBuilder because of docs.microsoft.com/en-us/aspnet/core/migration/… so rename CreateWebHostBuilder to BuildWebHost and migration will find BuildWebHost and take DbContext from it.
  • user3012760
    user3012760 almost 5 years
    Thank you, the only solution that worked for me was to set the web project as startup project and that is exactly what needed to be done.
  • Chaim Eliyah
    Chaim Eliyah almost 5 years
    WHAT. This should be advertised on every page dealing with this issue are you serious. Instant success. Thank you.
  • Ľuboš Pilka
    Ľuboš Pilka almost 5 years
    Thank you, kind of same thing happened to me. I had to change startup project to the place where Startup/Program classes exists. The error message is a bad joke.
  • upkit
    upkit almost 5 years
    Output messages were really frustrating. I had no startup project selected, unexpectedly. This was the reason why dbContext could not be created. Thanks.
  • Azri Zakaria
    Azri Zakaria almost 5 years
    Thanks mate, Solved after spend 2 hours to configure without using IDesignTimeDbContextFactory
  • D Todorov
    D Todorov over 4 years
    Save my day !!! It is very strange error. I`m using .net core 3.0 with preview 7 and this error stil exist
  • sherox
    sherox over 4 years
    @DTodorov read this devblogs.microsoft.com/dotnet/…
  • Sergey_T
    Sergey_T over 4 years
    Thanks for "-Verbose" flag. It has helped me to find the root cause of the exception.
  • Naveed Khan
    Naveed Khan over 4 years
    Thanks you sir ... A lot of my time is saved
  • Ali Bayat
    Ali Bayat over 4 years
    D Todorov Just rename BuildWebHost() to CreateHostBuilder()
  • Avrohom Yisroel
    Avrohom Yisroel over 4 years
    This is a fantastic tip, should be the accepted answer
  • WernerCD
    WernerCD over 4 years
    I'm using a Worker as a base and ran into this with Verbose: No static method 'CreateHostBuilder(string[])' was found on class 'Program'.. I had moved stuff around and renamed things - it recognized the CreateHostBuilder. For what it's worth... docs.microsoft.com/en-us/aspnet/core/fundamentals/host/…
  • sherox
    sherox over 4 years
    @WernerCD Cuz Worker uses CreateHostBuilder() method that implements IHostBuilder of Net Core 3
  • WernerCD
    WernerCD over 4 years
    @sherox Yeah, my point being simply that this answer says "you need static CreateWebHostBuilder()" - the same applies to the console application. You need "static CreateHostBuilder()" method. This answer got me in that direction. I had "rearranged" things so that wasn't present.
  • Sarah
    Sarah over 4 years
    Thank you so much, this helped me find my problem and solve it. In my case, it was a "No parameterless constructor defined for type 'Data.Access.DAL.MainDbContext'.", and therefore, I just removed the parameters from the constructor and it worked like magic!
  • Adam Carr
    Adam Carr about 4 years
    For reference this should be the way to solve the issue. I found out exactly what the issue was with my error.
  • David Klempfner
    David Klempfner over 3 years
    I got The term 'add-migration' is not recognized. Just adding --verbose to $ dotnet ef migrations worked for me.