TL; DR如何在单个请求中使用范围为DbContext
的多个查询?
我是EntityFrameworkCore的新手,我在使用DbContext
时遇到了麻烦,我正在使用AddScoped
将其添加到DI容器中(尽管我不对此有所了解,但这只是我的意思)请阅读在线阅读作为正确的选择)。
我有一个WidgetRepository
,可以通过ID或制造商ID查找Widget
,如下所示:
public class WidgetRepository
{
private readonly WidgetDbContext _widgetDbContext;
public WidgetRepository(WidgetDbContext widgetDbContext)
{
_widgetDbContext = widgetDbContext;
}
public Widget FindById(string id)
{
using (var context = _widgetDbContext)
{
var widget = context.Widget.Include("Identifiers")
.FirstOrDefault(w => w.Id.Equals(id));
return widget;
}
}
public IList<Widget> FindByManufacturerId(string manufacturerId)
{
using (var context = _widgetDbContext)
{
var widgets = context.Widget.Include("Identifiers")
.Where(w => w.Identifiers.SingleOrDefault(identifier => identifier.Type.Equals("manufacturerId") && identifier.Value.Equals(manufacturerId)));
return widgets;
}
}
}
我需要允许用户输入一个ID,而无需事先知道它是小部件ID还是制造商ID。因此,我有下面的课程做到这一点:
public class SearchById
{
private readonly WidgetRepository _widgetRepository;
public SearchById(WidgetRepository widgetRepository)
{
_widgetRepository = widgetRepository;
}
public IList<Widget> Search(string id)
{
var widget = _widgetRepository.FindById(id);
if (widget != null) {
return new List<Widget> {widget};
}
else return _widgetRepository.FindByManufacturerId(id);
}
}
我遇到的问题是,当_widgetRepository
从FindById
返回时,它会处理其WidgetDbContext
,这意味着当我对FindByManufacturerId
进行后续调用时,WidgetDbContext
不再存在。
如何使WidgetDbContext
在整个请求中可重复用于多个查询?
您的问题是您要在WidgetRepository类的每个方法中放置DbContext。不要那样做
您应该让DI容器管理DbContext的寿命。它将根据您的注册方式创建新实例并处置旧实例(例如,示例中的AddScoped)。
删除那些方法中的using语句,您应该能够在相同范围内对相同上下文执行多次调用(请注意,如果来自不同线程,则不要访问)。>>