在异步操作中获取DbContext

问题描述

我正在将网站从ASP MVC重写/移动到ASP MVC Core。该应用程序具有一个动态菜单,该菜单取决于已登录用户。为了构建菜单,每个控制器都从一个自定义BaseController派生而来,后者在ViewBag菜单项中进行设置,稍后,在Layout中,这些项被检索并作为参数传递给PartialView

public BaseController:Controller
{
    public BaseController()
    {
          ...
          ViewBag.Menu=Utils.GetMenu();
          ...
    }
}

我不想使用与编写旧代码的家伙相同的逻辑。因此,我想使用ViewComponent来渲染菜单。但是我对这种方法有疑问。在调用方法中,我需要查询菜单项。现在,我从服务提供商(HttpContext.RequestServices)获得了一个DbContext实例,并使用它来查询所需的任何数据。但是从Layout异步调用了Invoke函数,我知道将DbContext发送到async方法不是很好:

<cache expires-after="@TimeSpan.FromHours(2)" enabled="true">
       @await Component.InvokeAsync(typeof(Admin.ViewComponents.MeniuViewComponent))
</cache>

这是一个方法吗?在Invoke方法(或任何其他async方法或操作)中使用DbContext(在Startup中注册为Scoped)并使用它是否安全?而且如果不是一个好主意,我该如何处理需要async方法从db获取数据的这种情况?

解决方法

在我的项目中,我有一个案例要从asp.net内核中的HostedService中获取DbContext。

我将IServiceProvider注入了构造函数中并构建了自己的作用域,以获取注册的DbContext:

private readonly IServiceProvider _serviceProvider;
public BaseController(IServiceProvider provider){
  _serviceProvider = provider;
}

private void DoSth(){
  using var scope = _serviceProvider.CreateScope();
  var db = scope.ServiceProvider.GetRequiredService<YOUR_DbContext_CLASS>();

  ... //do something great stuff here with the database
}
,

我认为您可以直接在ViewComponent中依赖注入DbContext

function high(scorel)
    local record,leaders = 0,{}
    for name,score in pairs(scorel) do
        if score > record then 
           record = score
           leaders = {name}
        elseif score == record then
           table.insert (leaders,name)
        end
    end
    return leaders,record
end
local leaders,record = high(score)
if #leaders > 0 then
    print ('Highest score (' .. tostring(record) .. ') belongs to ' .. concat (leaders,','))
end

有关更多详细信息,请参阅doc

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...