在异步操作中获取 DbContext
Get DbContext in async action
我正在重写/移动一个网站,从 ASP MVC 到 ASP MVC Core。此应用程序有一个动态菜单,该菜单取决于登录用户。为了构建菜单,每个控制器都派生自自定义 BaseController
,他在 ViewBag
菜单项中设置,稍后,在布局中,这些项被检索并作为参数传递给 PartialView
.
public BaseController:Controller
{
public BaseController()
{
...
ViewBag.Menu=Utils.GetMenu();
...
}
}
我不想使用与编写旧代码的小伙子们相同的逻辑。所以我想用一个 ViewComponent
来渲染菜单。但是我对这种方法有疑问。在 Invoke 方法中,我需要查询菜单项。现在我从服务提供商 (HttpContext.RequestServices
) 获得了一个 DbContext 实例,我用它来查询我需要的任何数据。但是 Invoke 函数是从 Layout
异步调用的,我知道将 DbContext 发送到 async
方法不是很好:
<cache expires-after="@TimeSpan.FromHours(2)" enabled="true">
@await Component.InvokeAsync(typeof(Admin.ViewComponents.MeniuViewComponent))
</cache>
这是一个好方法吗?在 Invoke 方法(或任何其他 async
方法或操作)中获取 DbContext(在 Startup 中注册为 Scoped)并使用它是否安全?如果这不是一个好主意,我应该如何处理这种需要在 async
方法中从数据库获取数据的情况?
我在我的项目中遇到过从 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
public class MenuViewComponent : ViewComponent
{
private readonly MenuDbContext _context;
public TopMenuViewComponent(MenuDbContext context)
{
_context = context;
}
public async Task<IViewComponentResult> InvokeAsync()
{
var model = _context.MenuItems.ToList();
return View("Default", model);
}
}
详情请参考doc。
我正在重写/移动一个网站,从 ASP MVC 到 ASP MVC Core。此应用程序有一个动态菜单,该菜单取决于登录用户。为了构建菜单,每个控制器都派生自自定义 BaseController
,他在 ViewBag
菜单项中设置,稍后,在布局中,这些项被检索并作为参数传递给 PartialView
.
public BaseController:Controller
{
public BaseController()
{
...
ViewBag.Menu=Utils.GetMenu();
...
}
}
我不想使用与编写旧代码的小伙子们相同的逻辑。所以我想用一个 ViewComponent
来渲染菜单。但是我对这种方法有疑问。在 Invoke 方法中,我需要查询菜单项。现在我从服务提供商 (HttpContext.RequestServices
) 获得了一个 DbContext 实例,我用它来查询我需要的任何数据。但是 Invoke 函数是从 Layout
异步调用的,我知道将 DbContext 发送到 async
方法不是很好:
<cache expires-after="@TimeSpan.FromHours(2)" enabled="true">
@await Component.InvokeAsync(typeof(Admin.ViewComponents.MeniuViewComponent))
</cache>
这是一个好方法吗?在 Invoke 方法(或任何其他 async
方法或操作)中获取 DbContext(在 Startup 中注册为 Scoped)并使用它是否安全?如果这不是一个好主意,我应该如何处理这种需要在 async
方法中从数据库获取数据的情况?
我在我的项目中遇到过从 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
public class MenuViewComponent : ViewComponent
{
private readonly MenuDbContext _context;
public TopMenuViewComponent(MenuDbContext context)
{
_context = context;
}
public async Task<IViewComponentResult> InvokeAsync()
{
var model = _context.MenuItems.ToList();
return View("Default", model);
}
}
详情请参考doc。