实体框架核心 - 迁移 - 没有为此对象定义的无参数构造函数

时间:2017-04-19 16:16:08

标签: c# entity-framework asp.net-core entity-framework-core

我正在使用Visual Studio 2017中最新的.Net Core和EF Core。我创建了一个模型,它运行良好。我已经做了一些修改,当我尝试添加新的迁移时出现以下错误:

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.

我比较了自上次检查以来的代码并注释掉了某些代码块以查看错误是否仍然存在以及我注释掉了什么,它仍然会失败并出现相同的错误。

问题:有没有办法获得有关WHAT类型没有无参数构造函数的更详细信息?或者甚至从VS中运行它并且可能得到一个断点?

更新:根据部分评论,这里有一些代码。

对于DbContext覆盖

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;");
  }

  ...
}

我确实有一个IDbContextFactory,但它没有在任何地方被引用,并且没有引用。根据第二条评论中提供的链接,不确定这是否存在问题。如果内存服务,只要IDbContextFactory在解决方案中,就应该找到它吗?

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);
  }
}

我的Startup.cs班级

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
}

更新2:Solutiuon 看到我正在学习ASP.Net Core我正在阅读大量网站(包括docs.microsoft.com),我已经在IDbContextFactory代码中添加了一些内容,如上所示。我从代码中删除了它,错误消失了,所有内容都构建并创建了迁移。

我打算将@alessalessio标记为我认为的答案(还没有测试过),在ILoggerFactory loggerFactory构造函数中取出AlmanacDbFactory依赖关系也可以。

4 个答案:

答案 0 :(得分:6)

设计时工具会尝试自动查找应用程序如何创建DbContext类型的实例。如果EF无法找到初始化DbContext的合适方法,则可能会遇到此错误。

选项: 1-创建无参数构造函数

  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

答案 1 :(得分:2)

如果您有用于上下文的单独项目。 与目标项目一起设置启动项目

dotnet ef migrations add InitialCreate -s .\src\WebUI\  -p .\src\Infrastructure\ --verbose

答案 2 :(得分:0)

我有同样的问题。当我将ApplicationUser的实现更改为具有Guid ID的用户时,我的问题就开始了。

public class User : IdentityUser<Guid>

首先,我开始遇到一些疯狂的错误,并将DbContext设置为:

public class NgSchoolsContext : IdentityDbContext<User, IdentityRole<Guid>, Guid>

我开始遇到“无参数构造函数”错误。 最终解决的是在“启动”中更改“角色”配置:

services.AddIdentityCore<User>() .AddEntityFrameworkStores<NgSchoolsContext>() .AddRoles<IdentityRole<Guid>>() .AddDefaultTokenProviders();

注意IdentityRole部分。您不需要实现任何东西,只需将其放置成这样即可。它应该开箱即用。 然而!!您的迁移将失败,您将不得不从头开始重建数据库。实体无法处理以下事实:他的所有主键都从字符串(或其他任何东西)移到了Guid,并且无法更新数据库。 好吧,这至少更容易解决。删除数据库,删除所有迁移,添加迁移(新的初始)和更新数据库。如果出现正常错误消息,这将非常容易。

答案 3 :(得分:0)

在尝试添加迁移时,我遇到了相同的错误“没有为类型定义无参数构造函数”。 事实证明,在运行ef migrations时,实体框架会在启动项目Program.cs中传递参数 出于安全原因,string[] args已被删除。添加此按钮即可解决问题。