Как избежать сохранения всего совокупного корня при добавлении дочерней сущности? - PullRequest
5 голосов
/ 16 декабря 2011

У меня есть модель домена с совокупным корнем:

public interface IAggregateRoot {
    public string Id { get; }

    public string Foo { get; set; }
    public int Bar { get; set; }

    public IList<IChildEntity> Children { get; }
}

Коллекция Children имеет тенденцию становиться очень большой, и я буду лениво загружать ее, когда экземпляр IAggregateRoot будет получен через IAggregateRootRepository. Моя проблема в этом; если я хочу добавить IChildEntity в коллекцию детей IAggregateRoot, как мой репозиторий может позволить мне избежать сохранения всей совокупности?

Например, скажем, мой IAggregateRootRepository должен был выглядеть следующим образом:

public interface IAggregateRootRepository {
    public IAggregateRoot GetById(string id);

    public void AddOrUpdate(IAggregateRoot root);
}

Затем я могу добавить в коллекцию Children, получив экземпляр IAggregateRoot через IAggregateRootRepository.GetById (), добавив дочерний элемент в коллекцию Children, а затем сохранив его все через IAggregateRootRepository.AddOrUpdate (). Это, однако, сохранит весь совокупный корень вместе с его огромной коллекцией дочерних элементов каждый раз, когда я добавляю дочернюю сущность. Я думаю, я бы мог обойти это, если бы мой репозиторий выглядел так:

public interface IAggregateRootRepository {
    public IAggregateRoot GetById(string id);

    public void AddOrUpdate(IAggregateRoot root);
    public void AddOrUpdate(IChildEntity child);
}

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

Существуют ли другие, более эффективные способы избежать этой проблемы?

Ответы [ 2 ]

5 голосов
/ 16 декабря 2011

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

Тогда ваш исходный агрегированный корень не будет содержать дочерние объекты, а скорее ссылки на них (так как они теперь сами являются агрегированными корнями - а связи между агрегированными корнями должны быть через ссылочные ключи).Это также поможет с вашей ленивой стратегией загрузки.

Надеюсь, это поможет:)

0 голосов
/ 16 декабря 2011

Обычно ORM заботится об обновлениях всего агрегата в базе данных. Он обнаруживает изменения, внесенные в извлеченные объекты, и сохраняет только измененные объекты совокупности.

Так что, если вы только добавляете дочерний элемент в корень, и у вас нет другой модификации в совокупности. Затем ORM вставит только новую запись для дочерней сущности и оставит корневой агрегат, а остальные дочерние записи - одни.

...