Повторно использовать DbContext в одном запросе? - PullRequest
0 голосов
/ 04 октября 2019

TL; DR Как использовать область действия DbContext для выполнения нескольких запросов в рамках одного запроса?

Я новичок в EntityFrameworkCore, и у меня возниклопроблема с DbContext, которую я добавляю в DI-контейнер, используя AddScoped (хотя я не привязан к этому, это то, что я прочитал в Интернете, как правильно).

У меня есть WidgetRepository, который позволяет мне искать Widget s по идентификатору или по идентификатору производителя, например:

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

Мне нужно разрешить пользователю вводить идентификатор без моего ведома взаранее, будь то идентификатор виджета или идентификатор производителя. Итак, у меня есть следующий класс, который делает это:

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 многоразовым для нескольких запросов по всему запросу?

1 Ответ

0 голосов
/ 10 октября 2019

Ваша проблема в том, что вы используете DbContext в каждом методе класса WidgetRepository. Не делай этого.

Вы должны позволить контейнеру DI управлять временем жизни DbContext. Он создаст новые экземпляры и удалит старые в зависимости от того, как вы их зарегистрировали (например, AddScoped в вашем образце).

Удалите операторы использования из этих методов, и вы сможете выполнять несколько вызовов в одном и том же контексте вта же область (просто будьте осторожны, чтобы не получить доступ, если из другого потока).

...