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();
}
Adding a Migration So, firstly, you need to create a migration. Open the Package Manager Console from the menu Tools -> NuGet Package Manager -> Package Manager Console in Visual Studio and execute the following command to add a migration.
From the Tools menu, select NuGet Package Manager > Package Manager Console. The enable-migrations command creates a Migrations folder in the ContosoUniversity project, and it puts in that folder a Configuration. cs file that you can edit to configure Migrations.
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
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'.
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.
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>();
});
}
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)
{ }
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With