在新的MVC核心中,似乎将上下文获取到控制器的标准方法是这样做
public class BaseController : Controller
{
public readonly ReportDBContext _db;
public BaseController(ReportDBContext db)
{
_db = db;
}
}
然后我可以使用
public class HomeController : BaseController
{
public HomeController(ReportDBContext db) : base(db) { }
}
使这在所有其他控制器中更容易一些。 通常 Asp.net MVC 中,我可以随时通过使用new ReportDBContext()
获取上下文
现在是否有类似的方法,或者我是否必须在asp.core MVC中的所有控制器中都有上下文?
感谢@mm8的回答,如果您决定使用依赖注入,那么您可以按照以下步骤操作。
假设您已经这样定义ReportDBContext
:
public class ReportDBContext : DbContext
{
public DbSet<Sample> Samples { get; set; }
//...
public ReportDBContext(DbContextOptions<ReportDBContext> options) : base(options)
{
//...
}
}
因此,您需要像这样配置startup.cs
:
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
//...What needed
services.AddDbContext<ReportDBContext>(options => options.UseSqlServer("Connection string to your DB"));
//...What needed
}
//...
}
因此,您可以轻松地将ReportDBContext
注入到类中,如下所示(例如,将其注入到其中一个控制器(:
[Route("api/[controller]")]
public class ValuesController : Controller
{
private readonly ReportDBContext _dbContext;
public ValuesController(ReportDBContext dbContext )
{
_dbContext = dbContext;
}
//...
}
您可以简单地将ReportDBContext
注入到BaseController
,而不是将其注入到项目中的每个控制器。
更新 1
如果不想将ReportDBContext
注入到每个构造函数中,则可以使用 HttpContext.RequestServices 按如下方式设计BaseController
:
public class BaseController : Controller
{
protected ReportDBContext DbContext => (ReportDBContext)HttpContext.RequestServices.GetService(typeof(ReportDBContext));
//...
}
[Route("api/[controller]")]
public class ValuesController : BaseController
{
//...
[HttpGet]
public List<Sample> Get() => DbContext.Samples.ToList();
}
在这里阅读更多内容:
- https://learn.microsoft.com/en-us/ef/core/miscellaneous/configuring-dbcontext
- http://www.binaryintellect.net/articles/17ee0ba2-99bb-47f0-ab18-f4fc32f476f8.asp
你还需要至少安装以下两个 NuGet 包:
- Microsoft.实体框架核心
- Microsoft.EntityFrameworkCore.SqlServer (如果数据库提供程序Microsoft SQL Server(
通常在 Asp.net MVC 中,我可以随时使用
new ReportDBContext
((...
现在,您可以执行相同的操作,即在控制器中显式创建新上下文。除了最佳实践之外,没有什么可以阻止您这样做。
使用依赖关系注入的一些好处是,您可以在Startup
类中定义依赖关系的生存期,并在所有控制器中重用它,并且可以在单元测试中模拟依赖关系。有关详细信息,请参阅文档和此问题。
但是,如果您不想或有理由不使用依赖注入,则当然不必使用依赖注入。编译器不会强制你定义接受依赖项的自定义构造函数。
ASP.NET Core 的架构建立在依赖注入之上。它甚至有一个内置的依赖注入容器,但你也可以使用其他人,如AutoFac或NInject。如果需要在多个操作中使用 DbContext,则可以使用构造函数注入,如示例中所示。
如果只需要一次,可以直接将其注入到操作方法中,如下所示:
public IActionResult Get([FromServices]ReportDbContext db)
{
…
}
依赖关系注入的使用使代码更易于测试。对于单元测试,您可以注入内存数据库上下文。
在我看来,这比自己构建 DbContext 还要少。它是由框架完成的。