СЭД «ДЕЛО»
Руководство пользователя
×

5.4 Контекст доступа к данным - IDataContext

Модуль - Eos.Delo.Platform.Storage.Module;
Пространство имен - Eos.Delo.Platform.Storage.Model.
Доступ к данным осуществляется с использованием Entity Framework через интерфейс IDataContext (наследуется от DbContext). Является scoped-сервисом.
Так как IDataContext является scoped-сервисом, он существует в рамках запроса, либо его нужно создавать через ServiceScopeFactory как локальную переменную, с использованием using для создания скопа. Нельзя держать IDataContext внутри singleton-сервиса как внутреннюю переменную, так как остается открытым соединение.
Рекомендации по работе с IDataContext:
-                     не нужно IDataContext хранить в свойствах/полях долгоживущих классов.
-                     т.к. IDataContext получаем из ServiceProvider, то за время его жизни отвечает тоже ServiceProvider - не нужно его брать в using и не нужно его явно вызывать Dispose().
-                     в ФЗ нужно внимательно следить, чтобы случайно не начать работать с корневым ServiceProvider-ом, обязательно создавать ServiceScope, и именно его брать в using или закрывать явным Dispose().
Ниже приведен пример получения и сохранения данных через IDataContext с использованием стандартных средств Entity Framework (Не рекомендуется пользоваться стандартными средствами, вместо этого используйте перегруженные методы (см. 5.4.1. Конвейер промежуточного ПО), чтобы запустить конвейер обработки и выполнить необходимые проверки и алгоритмы)
* Примечание: для изменения данных не рекомендуется использовать метод Update, так как он обновляет все поля в БД. Вместо этого используйте EnsureTracked из Eos.Delo.Platform.Storage.Exctensions, затем поменяйте поля и вызовите метод SaveChangesAsync.
* Примечание: для получения данных желательно использовать AsNoTracking, чтобы данные не попадали в ChangeTracker.
* Примечание: методы Add и Remove вызывают каскадное добавление и удаление сущностей, если к добавляемой сущности привязать другие сущности через навигационные свойства. Для того, чтобы избежать такого поведения используйте методы SetAddedState и SetDeletedState из Eos.Delo.Platform.Storage.Exctensions.
 
Пример получения и сохранения данных через IDataContext:
// Получение и сохранение данных через IDataContext
using Eos.Delo.Platform.Storage.Extensions;
using Eos.Delo.Platform.Storage.Model;
 
private readonly IDataContext _dataContext;
private readonly DataContextHelperService _dataContextHelper;
 
public MyClass(IDataContext dataContext, DataContextHelperService dataContextHelper)
{
    _dataContext = dataContext;
    _dataContextHelper = dataContextHelper;
}  
 
    public async Task SimpleAddressQueryAsync(MiddlewareContextBase baseContext)
        {
            var address = await _dataContext.Addresses.Where(b => b.IsnAddress == 1)
                .AsNoTracking()
                .FirstOrDefaultAsync();
 
            var address2 = await _dataContext.Addresses.Where(b => b.IsnAddress == 2)
                .AsNoTracking()
                .FirstOrDefaultAsync();
 
            var address3 = await _dataContextHelper.GetEntityByPrimaryKeyAsync(3);
 
            _dataContext.EnsureTracked(address3);
            address3.Note = "Тест3";
 
            _dataContext.EnsureTracked(address2);
            address2.Note = "Тест1";
 
            var citizen = await _dataContext.Citizens.Where(p => p.IsnCitizen == 3935)
                .AsNoTracking()
                .FirstOrDefaultAsync();
 
            var newAddress = _dataContext.CreateAddress();
            newAddress.IsnRegion = 4057229;
            newAddress.Note = "Тест";
            newAddress.IsnOwner = citizen.IsnCitizen;
            newAddress.KindOwner = 109;
            _dataContext.SetAddedState(newAddress);
            await _dataContext.SaveChangesAsync();
 
            _dataContext.SetDeletedState(address);
            await _dataContext.SaveChangesAsync();
        }
Онлайн помощь создана в Dr.Explain