Attempting to run add-migration mig1 is failing.
Exception message:
No parameterless constructor was found on 'ApplicationDbContext'. Either add a parameterless constructor to 'ApplicationDbContext' or add an implementation of 'IDbContextFactory<ApplicationDbContext>' in the same assembly as 'ApplicationDbContext'.
Stack trace:
Finding DbContext classes...
Microsoft.EntityFrameworkCore.Design.OperationException: No parameterless constructor was found on 'ApplicationDbContext'. Either add a parameterless constructor to 'ApplicationDbContext' or add an implementation of 'IDbContextFactory<ApplicationDbContext>' in the same assembly as 'ApplicationDbContext'. ---> System.MissingMethodException: No parameterless constructor defined for this object.
at System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck)
at System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark)
at System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark)
at System.Activator.CreateInstance(Type type, Boolean nonPublic)
at System.Activator.CreateInstance(Type type)
at Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.<>c__DisplayClass12_3.<FindContextTypes>b__13()
--- End of inner exception stack trace ---
at Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.<>c__DisplayClass12_3.<FindContextTypes>b__13()
at Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.CreateContext(Func`1 factory)
at Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.CreateContext(String contextType)
at Microsoft.EntityFrameworkCore.Design.Internal.MigrationsOperations.AddMigration(String name, String outputDir, String contextType)
at Microsoft.EntityFrameworkCore.Design.OperationExecutor.AddMigrationImpl(String name, String outputDir, String contextType)
at Microsoft.EntityFrameworkCore.Design.OperationExecutor.AddMigration.<>c__DisplayClass0_1.<.ctor>b__0()
at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.<>c__DisplayClass3_0`1.<Execute>b__0()
at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(Action action)
```c#
My program.cs has .UseStartup
And StartupPortalBackend has:
public void ConfigureServices(IServiceCollection services)
{
// Add framework services.
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
[snip]
And my ApplicationDbContext has:
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
}
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
[snip]
```
This looks pretty much the same as a default asp.net core with entityframework core identity project but for some reason I cannot add a migration whereas if I created a default project I can. This was originally created on a default project template but somewhere along the line simply stopped working - I have not had to migrate anything in a little while.
Microsoft.EntityFrameworkCore.SqlServer - 1.1.2
Microsoft.EntityFrameworkCore - 1.1.2
Operating system: Windows 10 latest updates
IDE: Visual Studio 2017 latest updates
I implemented IDbContextFactory<DataContext>
and removed OnModelCreating
to solve this issue:
public class DataContextFactory : IDbContextFactory<DataContext>
{
public DataContext Create(DbContextFactoryOptions options)
{
// Used only for EF .NET Core CLI tools (update database/migrations etc.)
var builder = new ConfigurationBuilder()
.SetBasePath(Path.Combine(Directory.GetCurrentDirectory()))
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);
var config = builder.Build();
var optionsBuilder = new DbContextOptionsBuilder<DataContext>()
.UseSqlServer(config.GetConnectionString("SearchDataContext"));
return new DataContext(optionsBuilder.Options);
}
}
See #8328 for additional context.
@bricelam - #8328 was fixed in preview1. Does it have same effect in 1.1.2 release too?
We only look in the class "Startup" for "ConfigureServices". Either rename the class as "Startup", implement "IStartup", or use the IDbContextFactory as you suggest.
@programulya sorry for my stupidity, but how would I then use this code? Like where would I put this code, and then how would I call it? Seriously sorry for this, but I'm really struggling here 馃槩.
Hi @robquinn, maybe it's already solved in new versions because the issue was in version netcoreapp1.1. Regarding that solution I created MigrationsHelper
:
public static class MigrationsHelper
{
public static void MigrateDatabase()
{
var dbFactory = new DataContextFactory();
var dbContext = dbFactory.Create(new DbContextFactoryOptions());
dbContext.Database.Migrate();
}
public static IConfigurationRoot GetConfigFile()
{
var environmentName = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
var builder = new ConfigurationBuilder()
.SetBasePath(Path.Combine(Directory.GetCurrentDirectory()))
.AddJsonFile("appsettings.json", false, true)
.AddJsonFile($"appsettings.{environmentName}.json", optional: true)
.AddEnvironmentVariables();
var config = builder.Build();
return config;
}
}
and call it from Startup
:
public Startup(IHostingEnvironment env)
{
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
.AddEnvironmentVariables();
this.env = env;
this.config = builder.Build();
var logPath = this.config.GetSection("LogPath").Value;
Log.Logger = new LoggerConfiguration()
.Enrich.FromLogContext()
.WriteTo.RollingFile(logPath, shared: true)
.CreateLogger();
MigrationsHelper.MigrateDatabase();
}
Good luck ;)
Most helpful comment
I implemented
IDbContextFactory<DataContext>
and removedOnModelCreating
to solve this issue: