Допустим, у вас есть объект домена:
class ArgumentEntity
{
public int Id { get; set; }
public List<AnotherEntity> AnotherEntities { get; set; }
}
И у вас есть контроллер веб-API ASP.NET, чтобы справиться с этим:
[HttpPost("{id}")]
public IActionResult DoSomethingWithArgumentEntity(int id)
{
ArgumentEntity entity = this.Repository.GetById(id);
this.DomainService.DoDomething(entity);
...
}
Он получает идентификатор сущности, загружает сущность по идентификатору и выполняет на ней некоторую бизнес-логику с помощью службы домена.
Проблема. Проблема связана со связанными данными. ArgumentEntity имеет коллекцию AnotherEntities, которая будет загружена EF, только если вы явно попросите сделать это с помощью методов Include/Load. DomainService является частью бизнес-уровня и ничего не должен знать о сохраняемости, связанных данных и других концепциях EF.
Метод службы DoDomething ожидает получить экземпляр ArgumentEntity с загруженной коллекцией AnotherEntities. Вы бы сказали - это просто, просто включите необходимые данные в Repository.GetById и загрузите весь объект с соответствующей коллекцией.
Теперь давайте вернемся от упрощенного примера к реальности большого приложения:
ArgumentEntity намного сложнее. Он содержит несколько связанных коллекций, и связанные объекты также имеют свои связанные данные.
У вас есть несколько методов DomainService. Каждый метод требует загрузки различных комбинаций связанных данных.
Я мог представить возможные решения, но все они далеки от идеальных:
Всегда загружайте весь объект ->, но это неэффективно и часто невозможно.
Добавьте несколько методов репозитория: GetByIdOnlyHeader, GetByIdWithAnotherEntities, GetByIdFullData для загрузки определенных подмножеств данных в контроллер ->, но контроллер узнает, какие данные загружать и передавать каждому методу службы.
Добавьте несколько методов репозитория: GetByIdOnlyHeader, GetByIdWithAnotherEntities, GetByIdFullData для загрузки определенных подмножеств данных в каждый метод службы -> это неэффективно, запрос sql для каждого вызова метода службы. Что, если вы вызовете 10 сервисных методов для одного действия контроллера?
Каждый метод домена вызывает метод репозитория для загрузки дополнительных необходимых данных (например: EnsureAnotherEntitiesLoaded) -> это уродливо, потому что моя бизнес-логика узнает о концепции EF связанных данных.
Вопрос: как бы вы решили проблему загрузки необходимых связанных данных для объекта перед их передачей на бизнес-уровень?