在单个请求中重用DbContext?

问题描述 投票:0回答:1

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);
    }
}

我遇到的问题是,当_widgetRepositoryFindById返回时,它会处理其WidgetDbContext,这意味着当我对FindByManufacturerId进行后续调用时,WidgetDbContext不再存在。

如何使WidgetDbContext在整个请求中可重复用于多个查询?

entity-framework-core dbcontext
1个回答
0
投票

您的问题是您要在WidgetRepository类的每个方法中放置DbContext。不要那样做

您应该让DI容器管理DbContext的寿命。它将根据您的注册方式创建新实例并处置旧实例(例如,示例中的AddScoped)。

删除那些方法中的using语句,您应该能够在相同范围内对相同上下文执行多次调用(请注意,如果来自不同线程,则不要访问)。>>

© www.soinside.com 2019 - 2024. All rights reserved.