繁体   English   中英

有没有更好的方法将 dbcontext 添加到 Asp.core MVC controller?

[英]Is there any better way to add the dbcontext to a Asp.core MVC controller?

在新的 MVC 核心中,似乎将上下文获取到 controller 的标准方法是这样做

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 ,而不是将其注入项目中的每个 controller。

更新 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://docs.microsoft.com/en-us/ef/core/miscellaneous/configuring-dbcontext
  2. http://www.binaryintellect.net/articles/17ee0ba2-99bb-47f0-ab18-f4fc32f476f8.asp

您还需要至少安装这两个 NuGet 软件包:

  1. Microsoft.EntityFrameworkCore
  2. Microsoft.EntityFrameworkCore.SqlServer (如果数据库提供者是 Microsoft SQL 服务器)

通常在 Asp.net MVC 中,我可以随时使用new ReportDBContext () 获取上下文...

您也可以这样做,即现在在 controller 中显式创建一个新上下文。 除了最佳实践,没有什么可以阻止您这样做。

使用依赖注入的一些好处是,您可以在Startup class 中定义依赖项的生命周期,并在所有控制器中重用它,并且您可以在单元测试中模拟依赖项。 请参阅文档此问题以获取更多信息。

但是,如果您不想或有理由不这样做,您当然不必使用依赖注入。 编译器不会强制您定义一个接受依赖项的自定义构造函数。

ASP.NET Core 的架构建立在依赖注入之上。 它甚至有一个内置的依赖注入容器,但您也可以使用其他容器,如 AutoFac 或 NInject。 如果您在多个操作中需要 DbContext,则可以使用构造函数注入,就像在您的示例中一样。

如果你只需要一次,你可以直接将它注入到 action 方法中,如下所示:

public IActionResult Get([FromServices]ReportDbContext db) 
{ 
   …
} 

依赖注入的使用使您的代码更具可测试性。 对于您的单元测试,您可以注入一个 InMemory DbContext。

在我看来,这甚至比自己构建 DbContext 还要少。 它是由框架完成的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM