I am working with the latest .Net Core and EF Core in Visual Studio 2017. I have created a model and it was working great. I have since made some modifications and am getting the following error when I try to add a new migration:
Build succeeded.
0 Warning(s)
0 Error(s)
Time Elapsed 00:00:09.08
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.Activator.CreateInstance(Type type, Boolean nonPublic)
at System.Activator.CreateInstance(Type type)
at Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.<>c__DisplayClass12_0.<FindContextTypes>b__3()
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.OperationBase.<>c__DisplayClass3_0`1.<Execute>b__0()
at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(Action action)
No parameterless constructor defined for this object.
I have compared my code since the last check in and have commented out certain chunks of code to see if the error persists and whatever I comment out, it still fails with the same error.
Question: Is there a way to get more detailed information on exactly WHAT type does not have a parameterless constructor? Or even run this from within VS and perhaps get a breakpoint?
Update: Based on some of the comments, here is some code.
For the DbContext
override
public class AlmanacDb : IdentityDbContext<ApplicationUser, ApplicationRole, int> {
private readonly ILogger logger;
public AlmanacDb(DbContextOptions<AlmanacDb> options, ILoggerFactory loggerFactory) : base(options) {
this.logger = loggerFactory.CreateLogger<AlmanacDb>();
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) {
optionsBuilder.UseSqlServer("Server=.\\SQLExpress;Database=Almanac;Trusted_Connection=True;MultipleActiveResultSets=True;");
}
...
}
I do have a IDbContextFactory
but it is not referenced anywhere and worked without a reference. Not sure if this is a problem or not based on a link provided in the 2nd comment. If memory serves, as long as the IDbContextFactory
is within the solution, it should find it?
public class AlmanacDbFactory : IDbContextFactory<AlmanacDb> {
private IConfigurationRoot configuration;
private readonly ILoggerFactory loggerFactory;
public AlmanacDbFactory(ILoggerFactory loggerFactory) {
var builder = new ConfigurationBuilder()
.SetBasePath(System.AppContext.BaseDirectory)
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);
this.configuration = builder.Build();
this.loggerFactory = loggerFactory;
}
public AlmanacDb Create(DbContextFactoryOptions options) {
var optionsBuilder = new DbContextOptionsBuilder<AlmanacDb>();
optionsBuilder.UseSqlServer(
configuration.GetConnectionString("AlmanacSQL"), m => { m.EnableRetryOnFailure(); }
);
return new AlmanacDb(optionsBuilder.Options, loggerFactory);
}
}
My Startup.cs
class
public void ConfigureServices(IServiceCollection services) {
try {
services.AddDbContext<AlmanacDb>(options =>
options.UseSqlServer(Configuration.GetConnectionString("AlmanacSQL"))
);
services.AddScoped(typeof(IRepository<>), typeof(Repository<>));
services.AddIdentity<ApplicationUser, ApplicationRole>()
.AddEntityFrameworkStores<AlmanacDb, int>()
.AddDefaultTokenProviders();
services.AddScoped<SignInManager<ApplicationUser>, AvantiaSignInManager<ApplicationUser>>();
services.AddAuthorization(x => {
x.AddPolicy("EmployeeOnly", p => p.RequireClaim("EmployeeNumber"));
});
services.AddMvc();
} catch (Exception e) {
Console.WriteLine(e.ToString());
throw;
}
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, AlmanacDb context) {
... // Nothing actually touches the AlmanacDb within this code so I left it out
}
Update 2: Solutiuon
Seeing that I am learning ASP.Net Core I am reading a ton of sites (including docs.microsoft.com) at one point I put in the IDbContextFactory
code as you can see above. I removed that from my code and the error went away and everything built and created the migration.
I am going to mark @alessalessio as the answer as I assume (have not tested it yet) that taking out the ILoggerFactory loggerFactory
dependency within the AlmanacDbFactory
constructor will do the trick as well.
Design-time tools attempt to automatically find how your application creates instances of your DbContext type. If EF cannot find a suitable way to initialize your DbContext, you may encounter this error.
Options: 1- Either create a parameterless constructor
public AlmanacDb() { }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer(_connString);
}
private readonly string _connString = "<your conn string>";
2-
public AlmanacDb Create()
{
var optionsBuilder = new DbContextOptionsBuilder<AlmanacDb>();
optionsBuilder.UseSqlServer(connectionString);
return new AlmanacDb(optionsBuilder.Options);
}
https://docs.microsoft.com/en-us/ef/core/miscellaneous/configuring-dbcontext
If you have a separate project for context. set a startup project with the target project
dotnet ef migrations add InitialCreate -s .\src\WebUI\ -p .\src\Infrastructure\ --verbose
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