【问题标题】:no parameterless constructor defined for type dbcontext没有为类型 dbcontext 定义无参数构造函数
【发布时间】:2022-03-29 22:33:14
【问题描述】:

我在堆栈和其他网站中搜索了许多关于此错误的帖子,但这不是我的答案 这是我的 DbCintext

[Table("AspNetUsers")]
public class ApplicationUser : IdentityUser { }

public class EMSContext : IdentityDbContext<ApplicationUser> {
   

    public EMSContext (DbContextOptions<EMSContext> options) : base (options) { }

    public DbSet<Ambulance> Ambulances { get; set; }
 }

这是 mu StartUp.cs

 services.AddControllers();
        
        services.AddDbContext<EMSContext>(options =>
          options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

但是当我想生成 api 控制器时出现了这个错误

没有为类型 dbcontext 定义无参数构造函数

【问题讨论】:

  • 你能显示你试图解析 DbContext 的代码吗? (例如在控制器的构造函数中)
  • 另外,您是否在启动时配置身份服务? (例如致电AddIdentityAddEntityFrameworkStores&lt;EMSContext&gt;())。后一种方法可能是必要的

标签: c# asp.net-core-mvc dbcontext


【解决方案1】:

错误很明显,你没有无参数构造函数。

但话虽如此,工具不应该需要它,因为您正在调用AddDbContext 并传入您的连接字符串。工具支架控制器/等。通过实际运行您的程序,然后向主机的服务提供商请求DbContext。它通过查找具有非常具体的名称的方法来做到这一点。

我的猜测是您的主要Program.cs 没有遵循规定的模式,因此无法构造您的Host 也无法找到它的ServiceProvider

你的选择如下(我个人的选择是#2):

  • 如消息所述添加无参数构造函数
  • 确保您的主入口点对主机构建器方法使用正确的约定
  • 创建设计时上下文工厂

无参数构造函数

这是显而易见的答案,尽管并不总是可能的。此外,它不应该是必要的,因为脚手架有其他方式可以从您的DbContext 中读取。仅为此目的添加构造函数不是我不会做也不推荐的事情。

正确的命名/方法签名

脚手架在尝试运行您的程序时会寻找一个非常具体的方法签名。基本上,它正在寻找这样的东西:

public class Program
{
    public static void Main(string[] args)
        => CreateHostBuilder(args).Build().Run();

    // EF Core uses this method at design time to access the DbContext
    public static IHostBuilder CreateHostBuilder(string[] args)
        => Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(
                webBuilder => webBuilder.UseStartup<Startup>());
}

现在它不需要像这样完全了。重要的部分是CreateHostBuilder 方法的名称和签名。*

如果在尝试构建服务时出现任何错误,例如因为存在无法解析的依赖项或缺少配置,则此方法将失败。我很确定您会收到相同的错误或与 DI 相关的错误。**

设计时间工厂

假设 仍然 不起作用,或者您想要更好的控制,您可以为您的上下文创建一个 Design-Time Factory。该工具将扫描您的项目以查找实现 IDesignTimeDbContextFactory&lt;EMSContext&gt; 的类型,然后在脚手架期间使用它:

public class EMSContextFactory : IDesignTimeDbContextFactory<EMSContext>
{
    public EMSContext CreateDbContext(string[] args)
    {
        var optionsBuilder = new DbContextOptionsBuilder<EMSContext>();
        optionsBuilder.UseSqlServer("Your Connection String");

        return new EMSContext(optionsBuilder.Options);
    }
}

更多信息请参见this link

* 注意:您尚未指定您正在运行的 aspnet 核心版本。如果您没有使用通用主机 (Host.CreateDefaultBuilder),而是使用WebHost,那么预期的方法签名看起来会有些不同。也就是说,它将与创建具有相同设置的新项目相匹配。

如果您曾经为控制器编写过集成测试,WebApplicationFactory 会寻找类似的方法/签名。那些相同的签名应该满足控制器脚手架。除了上面的链接,我似乎找不到其他文档。

** 当脚手架运行时,它作为“生产”环境执行。如果由于处于“错误”环境中而导致服务解析/配置失败,则可能会发生 DI 错误。这是上下文工厂解决方案存在的原因之一。

【讨论】:

  • 一天前我真的掉进了这个陷阱,这是因为我重命名了CreateHostBuilder 方法。直到之后我才意识到这一点,我创建了一个自定义设计时工厂并搭建了我的控制器。无论哪种方式,我都很高兴了解这两种解决方案
  • Program.cs 中的所有签名都是正确的,但是当我添加 Design Time Factory 时它工作正常,
  • 那么可能其他服务之一在脚手架运行时无法正确解析。所以设计时工厂就是你所需要的
【解决方案2】:

错误正好位于这一行:

public EMSContext (DbContextOptions<EMSContext> options) : base (options) { }

DbContext 没有无参数构造函数...当然,因为你的构造函数接受一个参数 DbContextOptions 选项,

所以你有两个选择来修复它,修复对构造函数的调用或让构造函数接受 0 个参数

【讨论】:

  • configuring the context for DI 使用.AddDbContext 时,应将 DbContextOptions 传递给 DbContext 构造函数。所以可能是其他原因导致了这个问题
【解决方案3】:

这是我遇到的错误,听起来和你的很相似。

我在尝试创建视图时遇到了这个问题(红色圈出的那个)。我的问题是 Startup.cs 文件。我最近将 LeaveHistory... 重命名为 LeaveRequest...,在编辑 Startup.cs 文件时,我做出了错误的更改。

第 39 行应为:

services.AddScoped<ILeaveRequestRepository, LeaveRequestRepository>();  // no "I"

我收到的错误是 dbContext 类没有无参数构造函数 - 所以它完全具有欺骗性,或者至少没有那么有用。

所以对于其他看到此错误的人,不要当面接受它!我对这个项目相当深入,我的其他控制器都没有无参数构造函数,至少没有写出来。

想想你所做的其他文书更改——职业名称更改,诸如此类。也许错误消息实际上并不是看起来的那样,并且您在其他地方犯了一个小错误,只会产生令人困惑的错误消息。

【讨论】:

    猜你喜欢
    • 2015-01-22
    • 1970-01-01
    • 2014-02-28
    • 2023-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多