DDD с EF Core: рекомендации по добавлению дочерних объектов в совокупный кореньC#

Место общения программистов C#
Ответить
Anonymous
 DDD с EF Core: рекомендации по добавлению дочерних объектов в совокупный корень

Сообщение Anonymous »

Я провожу рефакторинг проекта для использования расширенного моделирования предметной области и DDD путем моделирования корневых агрегированных объектов (AR) и дочерних объектов. Я также создаю репозитории для каждого AR, чтобы предотвратить утечку доступа к базе данных в другие классы. Однако у меня возникли некоторые проблемы с дизайном.
У меня есть совокупный корень ProfileGroup, который состоит из авторизаций, которые позже можно назначать пользователям. ProfileGroup AR содержит следующие авторизации:

Код: Выделить всё

private List _authorizations = new();

public IReadOnlyCollection Authorizations => _authorizations;
Когда группа профилей определена, она может иметь полномочия, принадлежащие конкретному приложению. Приложение хранится в группе профилей, поэтому при добавлении новой авторизации в группу профилей мне необходимо подтвердить, что авторизация принадлежит правильному приложению.
Сами авторизации не создаются пользователями. Они предопределены и занесены в базу данных посредством миграции.
Каждая группа профилей может иметь до ~100 авторизаций. Группа профилей отвечает за поддержание этих авторизаций в допустимом состоянии (например, за обеспечение принадлежности авторизации правильному приложению).
Ранее логика добавления авторизации выглядела примерно так (псевдокод):
  • Проверьте, существует ли группа профилей:
    _context.ProfileGroups.AnyAsync(x => x.Id == id)
  • Проверьте, существует ли авторизация:
    _context.ProfileGroupAuthorizations.FirstOrDefaultAsync(x => x.Id == id)
    Если она не существует, создайте ее
    Если она существует, обновите ее
  • Добавьте авторизацию через:
    _context.ProfileGroupAuthorizations.Add(auth)
Прочитав книгу Эрика Эванса «Доменно-ориентированный дизайн», я увидел следующее:

Только АГРЕГАТНЫЕ КОРНИ можно получить непосредственно с помощью запросов к базе данных. Все остальные объекты должны быть найдены путем обхода ассоциаций.

Основываясь на этом, я реализовал ProfileGroupRepository, который извлекает только совокупный корень. Я перенес операции CRUD на сам домен и инкапсулировал логику с помощью методов, которые изменяют список частных _authorizations, например

Код: Выделить всё

public void AddAuthorization()
public void RemoveAuthorization()
Теоретически это работает хорошо. Однако я не уверен в одном важном моменте.
При получении корня агрегата всегда ли мне загружать весь агрегат, а затем выполнять операцию, или допустимо загружать только те дочерние объекты, которые мне нужны, например:

Код: Выделить всё

ProfileGroup? profileGroup = await _context.ProfileGroups .Include(x => x.Authorizations.Where(a => a.Id == authorizationId)) .FirstOrDefaultAsync(x => x.Id == profileGroupId);
Чтобы сохранить согласованность, следует ли мне всегда загружать полный агрегат?
Проблема заключается в том, что я использую шаблон исходящих данных для распространения этих изменений в N последующих баз данных, и загрузка всех дочерних объектов каждый раз кажется излишним.
Чтобы обеспечить соблюдение правил DDD, я понял, что мне не следует напрямую запрашивать или сохранять дочерние объекты за пределами корня агрегата. Однако для коллекций, которые могут содержать много строк, я не уверен, эффективна или необходима быстрая загрузка всего набора данных в агрегат.
Для агрегатов с небольшими коллекциями или отдельными дочерними объектами у меня есть разумный подход. Но когда дело доходит до более крупных отношений, подобных этой, или отношений «многие ко многим» в целом, я изо всех сил пытаюсь решить:
  • Должен ли объект отношения сам быть совокупным корнем?
  • Или он должен принадлежать одному из основных агрегатов?
  • Как мне сбалансировать правила согласованности DDD с проблемами производительности и масштабируемости?
Будем очень признательны за любые рекомендации по этому поводу. Спасибо!

Подробнее здесь: https://stackoverflow.com/questions/798 ... egate-root
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»