簡體   English   中英

實體框架核心 - 遷移 - 沒有為此對象定義無參數構造函數

[英]Entity Framework Core - Migration - No Parameterless Constructor Defined for this Object

我正在 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:解決方案看到我正在學習 ASP.Net Core,我正在閱讀大量網站(包括 docs.microsoft.com),我將IDbContextFactory代碼放入其中,如上所示。 我從我的代碼中刪除了它,錯誤消失了,所有內容都構建並創建了遷移。

我將把@alessalessio 標記為答案,因為我認為(尚未測試過)在AlmanacDbFactory構造函數中取出ILoggerFactory loggerFactory依賴項也可以解決問題。

設計時工具會嘗試自動查找應用程序如何創建 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

如果您有一個單獨的上下文項目。 使用目標項目設置啟動項目

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

我遇到過同樣的問題。 當我將 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 並且無法更新數據庫的事實。 嗯,這至少更容易解決。 刪除數據庫,刪除所有遷移,添加遷移(新初始)和更新數據庫。 如果是正常的錯誤消息,這將非常容易。

我在嘗試添加遷移時遇到了同樣的錯誤“沒有為類型定義無參數構造函數......”。 事實證明,當運行ef migrations實體框架時,在啟動項目 Program.cs 中傳遞參數時,出於安全原因刪除了string[] args 添加這個解決了這個問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM