Я бы реорганизовал это, чтобы позволить внешний контроль транзакций. Репозиторий не может знать объем единицы работы, частью которой являются различные вызовы чтения / записи, если только код, который выполняет вызовы, не сообщает об этом. Рассмотрите возможность настройки шаблона «единица работы»: не раскрывая конкретных деталей реализации хранилища данных, разрешите объектам, зависящим от репозитория, указать, что они начинают, отменяют или завершают «единицу работы».
public interface IRepository
{
public UnitOfWork BeginUnitOfWork()
public void CommitUOW(UnitOfWork unit)
public void AbortUOW(UnitOfWork unit)
public IQueryable<T> GetAll<T>(UnitOfWork unit)
public List<T> GetAll<T>()
public void Store<T>(T theObject, UnitOfWork unit)
public void Store<T>(T theObject)
}
Ваш репозиторий, вероятно, реализовал бы это, поддерживая частный словарь транзакций SQL, каждая из которых привязана к объекту UnitOfWork (это может быть так же просто, как пустой экземплярный класс, или он может предоставлять независимую от фреймворка информацию о состоянии или показателях). При выполнении операции с БД ваши абоненты сначала попросят начать UoW, и им будет выдан токен, который они будут использовать для идентификации контекста, в котором они делают вызов БД. Объект, который получает токен, может передать его другим классам, которые должны выполнять операции с БД в том же рабочем контексте. Единица работы будет оставаться открытой до тех пор, пока зависимый класс не сообщит репозиторию, что он завершен, что позволяет выполнять ленивые нагрузки и атомарные многооперационные процедуры.
Обратите внимание, что существуют перегрузки, которые не требуют единиц работы. Можно и возможно необходимо совершать простые вызовы без явного запуска единицы работы. В этих случаях ваш репозиторий может создать внутреннее UOW, выполнить запрошенную операцию и вернуть результаты. Однако, ленивая загрузка будет трудной или невозможной в этих случаях; вам придется извлечь весь набор результатов в список перед завершением внутреннего UoW.