我正在尝试在ASP.NET Core 2.1 API项目中注入一个简单的连接字符串。
appsettings.json:
{
"ConnectionStrings": {
"DefaultConnection": "Server=xxx.database.windows.net;Database=xxx;User Id=frontend;Password=xxx;"
}
}
Startup.cs:
public void ConfigureServices(IServiceCollection services)
{
var connStr = Configuration.GetConnectionString("DefaultConnection");
services.AddDbContext<DB>(options => options.UseSqlServer(connStr));
DbContext:
public class DB : DbContext
{
public DB(DbContextOptions<DbContext> options) : base(options) { }
public DB() { }
public DbSet<MenuItem> MenuItemList { get; set; }
}
我的控制器:
public class MenuItemsController : ControllerBase
{
DB _context;
public MenuItemsController(DB context)
{
_context = context;
}
// GET api/values
[HttpGet]
public ActionResult<IEnumerable<string>> Get()
{
try
{
var ddd = _context.MenuItemList.ToList();
}
catch(Exception ex)
{
Console.WriteLine(ex.Message);
}
return new string[] { "value1", "value2" };
}
}
我收到以下错误:
没有为此DbContext配置数据库提供程序。
从appsettings文件中正确读取了连接字符串,我缺少什么吗?我读过其他文章,人们只是在DB上下文中配置连接部分,但我更喜欢通过注入来实现。
最佳答案
这是数据库上下文类型DB
上的两个构造函数:
public DB(DbContextOptions<DbContext> options) : base(options) { }
public DB() { }
因此,当依赖项注入容器尝试解析数据库上下文时,它将查看那些构造函数,并尝试确定使用哪个构造函数来创建对象。
首先,它将查看期望
DbContextOptions<DbContext>
参数的对象。通常,DbContextOptions
被自动注册为AddDbContext<T>()
调用的一部分。但是,注册的类型是DbContextOptions
(非通用)和DbContextOptions<T>
。因此,对于您的情况,对于数据库上下文
DB
,仅注册类型DbContextOptions
和DbContextOptions<DB>
。因此,依赖项注入容器无法解析
DbContextOptions<DbContext>
,因此无法使用该构造函数。因此它将使用下一个恰好是空构造函数的构造函数。由于空的构造函数不支持任何配置,因此数据库上下文将是未配置的,并且在尝试使用它时会收到该错误。解决方案非常简单:在该构造函数中调整
DbContextOptions<>
类型。您可以使用DbContextOptions
或DbContextOptions<DB>
。通常首选后者,因为它允许您在同一应用程序中拥有多个数据库上下文,但是如果您只有一个数据库上下文,则也可以使用前者。我还建议您删除空的构造函数,以确保不会意外使用它:public DB(DbContextOptions<DB> options)
: base(options)
{ }