Список агрегатов внутри агрегата - PullRequest
0 голосов
/ 08 октября 2019

Я моделирую функциональность Студента и Посещаемости, используя агрегаты DDD. То, что я закончил, было студенческим классом, имеющим список записей Посещаемости. Я использую ядро ​​EF для загрузки студента вместе со всеми посещаемостями, связанными со студентом.

Так что каждый день будет регистрироваться запись посещаемости против студента. Запись о посещаемости может обновляться несколько раз в течение дня. Я закончил тем, что создал общедоступный метод в классе Student с именем CreateOrUpdateAttendance (Date date, AttendanceDetails посещаемость), который внутренне проверял бы, есть ли какие-либо записи о посещаемости на указанную дату, если не создавал новый экземпляр посещаемости, обновлял эту запись о посещаемости с предоставленной посещаемостьюдетали добавить / обновить список посещаемости, связанный с учеником. Таким образом, каждый раз, когда для учащегося обновляется / создается посещаемость, сущность студента запрашивается из базы данных вместе со всеми записями посещаемости. Студент запрашивается на основе идентификатора, полученного из входных данных, чтобы проверить, является ли предоставленный идентификатор действительным или нет.

Проблема в том, что по прошествии нескольких дней со студентом будет связано много записей посещаемости, что означает ненужное извлечение всех данных. записи посещаемости, связанные со студентом, которые приведут к плохой производительности запросов.

Является ли студент здесь правильным корнем? К сожалению, ядро ​​EF пока не поддерживает фильтрацию дочерних объектов.

Мой вопрос заключается в том, как справиться с вариантом использования, в котором дочерние сущности должны быть обновлены внутри агрегата. Более конкретно, одна сущность из списка сущностей внутри агрегата?

В этом случае следуетЯ отношусь к Посещаемости как к другой совокупности? Чтобы я мог запросить запись о посещаемости независимо от записи о студенте?

В итоге я сделал два вызова в базу данных: один для проверки студента (без загрузки посещаемости), а другой - для получения записи о посещаемости.

Я что-то здесь упускаю? Должен ли я переосмыслить свой дизайн? Любое руководство будет очень полезным.

1 Ответ

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

Является ли Student здесь правильным корнем?

Агрегат - это граница согласованности. Он существует, чтобы гарантировать, что сущности, содержащиеся в нем, находятся в согласованном (то есть действительном) состоянии, поскольку это относится к вашим бизнес-правилам. Вы еще не описали какие-либо бизнес-правила или проверки, которые должны быть обеспечены, поэтому я не знаю, что Студент является правильным Совокупным. Читайте дальше ...

К сожалению, ядро ​​EF пока не поддерживает фильтрацию дочерних объектов.

EF Core не поддерживает фильтрацию дочерних коллекций, но могут быть и другие способы. чтобы сделать это. Вот некоторый псевдокод:

var query = 
    from s in ctx.Students
    where s.Id == 1 // Student filter here
    select new 
    {
        Student = s,
        Student = 
            from sa in s.StudentAttendances
            where sa. // Apply filter here
            select sa
    };

// Perform the query against the DB and then return the Student object
// EF will wire up the relationships for you and because you went to the
// DB first before pulling the student, the data is local and you will
// have the full tree
var student = query.ToList().Select(x => x.Student).FirstOrDefault();

В этом случае я должен рассматривать Посещаемость как различную совокупность? Чтобы я мог запросить запись о посещаемости независимо от записи о студенте?

Это зависит от ваших бизнес-правил. Каковы времена жизни ученика и посещаемости? Может ли ученик иметь какое-либо количество посещений? Подумайте больше о ваших случаях использования записи и меньше о ваших случаях использования чтения. Вам нужно загрузить StudentAttendances вообще? Это просто вариант использования для чтения?

Также подумайте, достаточно ли ОДНОГО студенческого агрегата. Стоит ли загружать все записи о посещаемости, когда вы просто хотите изменить номер телефона? Так же, как у нас есть Ограниченные контексты, вы можете рассмотреть возможность создания Ограниченных агрегатов, например, вертикальных разделов Агрегата в Ограниченном контексте, разделяющих то, что звучит как один большой концепт, на несколько более мелких концепций.

У вас может быть:

  • Агрегат ученика с отфильтрованным списком посещений (как показано выше)
  • Агрегат ученика (как вы упомянули)
  • Агрегат StudentWithAttendance, который отделен от Агрегата ученика и обслуживает другой вариант использования

Я что-то здесь упускаю? Должен ли я переосмыслить свой дизайн?

Это зависит. Как правило, я бы предложил больше думать на уровне домена и меньше на уровне базы данных. Больше думай о Пишет, чем Читает.

EF заставляет нас, в некотором смысле, мыслить реляционно, даже когда мы моделируем наш Домен, но мы должны бороться с этим побуждением и переводить EF в простой механизм постоянства, где это возможно, и не позволять ему управлять нашим Доменом. решения.

...