实体框架核心-迁移-没有为此对象定义无参数构造函数 [英] Entity Framework Core - Migration - No Parameterless Constructor Defined for this Object

查看:69
本文介绍了实体框架核心-迁移-没有为此对象定义无参数构造函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

 构建成功。 
0警告
0错误

经过的时间00:00:09.08
System.MissingMethodException:没有为此对象定义无参数的构造函数。 System.RuntimeTypeHandle.CreateInstance(RuntimeType类型,布尔publicOnly,布尔noCheck,布尔& canBeCached,RuntimeMethodHandleInternal& ctor,布尔&bNeedSecurityCheck)中的
,System.RuntimeType.CreateInstanceSlow(布尔publicOnly,布尔skipCheckThis,布尔fillCache,StackCrawlMark& amp; StackMark)System.Activator.CreateInstance(类型类型,布尔非公共)处的
System.Activator.CreateInstance(Type类型)处的
Microsoft.EntityFrameworkCore.Design.Internal处的
。 DbContextOperations。<> c__DisplayClass12_0。< FindContextTypes> b__3()
在Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.CreateContext(Func`1 factory)
在Microsoft.EntityFrameworkCore.Design.Internal。 Microsoft.EntityFrameworkCore.Design.Internal.MigrationsOperations.AddMigration(String name,String outputDir,String contextType)的DbContextOperations.CreateContext(String contextType)
Microsoft.EntityFrameworkCore的
.Design.OperationExecutor.AddMigrationImpl(字符串名称,字符串outputDir,字符串contextType)
在Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase。<> c__DisplayClass3_0`1。< Execute> b__0()
在Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(Action action)
没有为此对象定义无参数构造函数。

自上次签入以来,我已经比较了我的代码,并注释掉了某些代码块以查看是否错误仍然存​​在,无论我如何注释,它仍然会失败,并显示相同的错误。



问题:有没有办法获取更多详细信息到底什么类型没有无参数构造函数?甚至可以从VS中运行它并可能获得断点?



更新:根据一些评论,下面是一些代码。 / p>

对于 DbContext 覆盖

 公共类AlmanacDb:IdentityDbContext< ApplicationUser,ApplicationRole,int> {

私人唯读ILogger记录器;

public AlmanacDb(DbContextOptions< AlmanacDb>选项,ILoggerFactory loggerFactory):base(options){
this.logger = loggerFactory.CreateLogger< AlmanacDb>();
}

受保护的覆盖无效void OnConfiguring(DbContextOptionsBuilder optionsBuilder){
optionsBuilder.UseSqlServer( Server = .\\SQLExpress; Database = Almanac; Trusted_Connection = True; MultipleActiveResultSets =真正;);
}

...
}

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

 公共类AlmanacDbFactory:IDbContextFactory< AlmanacDb> {

私有IConfigurationRoot配置;
私有只读ILoggerFactory loggerFactory;

公共AlmanacDbFactory(ILoggerFactory loggerFactory){
var builder = new ConfigurationBuilder()
.SetBasePath(System.AppContext.BaseDirectory)
.AddJsonFile( appsettings.json ,可选: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();}
);

返回新的AlmanacDb(optionsBuilder.Options,loggerFactory);
}
}

我的 Startup.cs

  public void ConfigureServices(IServiceCollection服务){
试试{
服务.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());
投掷;
}
}

public void Configure(IApplicationBuilder应用程序,IHostingEnvironment env,ILoggerFactory loggerFactory,AlmanacDb上下文){
... //实际上没有触及AlmanacDb这段代码,所以我忽略了它
}

更新2:Solutiuon
看到我正在学习ASP.Net Core,我读了很多网站(包括docs.microsoft.com),当时我把它放在 IDbContextFactory 代码,如上所示。我从代码中删除了该错误,错误消失了,一切都建立并创建了迁移。



我将@alessalessio标记为我认为的答案(没有进行了测试),在 AlmanacDbFactory 构造函数中删除 ILoggerFactory loggerFactory 依赖关系也可以解决问题。

解决方案

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



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

  public AlmanacDb(){} 
受保护的重写void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer (_connString);
}

私有只读字符串_connString =<您的conn字符串>;

2-

  public AlmanacDb Create()
{
var optionsBuilder = new DbContextOptionsBuilder< AlmanacDb>();
optionsBuilder.UseSqlServer(connectionString);

返回新的AlmanacDb(optionsBuilder.Options);
}

https://docs.microsoft.com/zh-cn/ef/core/miscellaneous/configuring-dbcontext


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

这篇关于实体框架核心-迁移-没有为此对象定义无参数构造函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆