有没有更好的方法将数据库上下文添加到Asp.core MVC控制器?



在新的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();
}

在这里阅读更多内容:

  1. https://learn.microsoft.com/en-us/ef/core/miscellaneous/configuring-dbcontext
  2. http://www.binaryintellect.net/articles/17ee0ba2-99bb-47f0-ab18-f4fc32f476f8.asp

你还需要至少安装以下两个 NuGet 包:

  1. Microsoft.实体框架核心
  2. 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 还要少。它是由框架完成的。

最新更新