#nhibernate
#nhibernate
Вопрос:
Учитывая приведенный ниже упрощенный класс, давайте предположим:
- у родительского элемента может быть относительно большое количество дочерних элементов (например, 1000)
- дочерняя коллекция загружается с задержкой
- мы загрузили один родительский элемент через его идентификатор из стандартного метода Get родительского хранилища и теперь собираемся прочитать свойство OldestChild
class Parent { public IList<Child> Children { get; set; } public Child OldestChild { get { return Children.OrderByDescending(c => c.Age).FirstOrDefault(); } }
Существует ли какой-либо наилучший практический подход при использовании NHibernate и репозиториев для удовлетворения обоих:
-
a) Следует выбрать старейшего дочернего элемента через совокупный корень (родительский) — [ie. без независимого запроса дочерней таблицы, например, через дочерний каталог с использованием родительского идентификатора]
-
b) Следует избегать загрузки всей дочерней коллекции в память (в идеале самый старый дочерний запрос должен обрабатываться БД)
Это кажется чем-то возможным и простым, но я не вижу очевидного способа достижения этого. Возможно, я что-то упускаю?
Я использую NHibernate 2.1, поэтому решение для этого было бы отличным, хотя скоро будет обновлено до 3.
Ответ №1:
Я бы создал специализированный метод в вашем репозитории, который возвращает самый старый дочерний элемент данного родительского элемента.
Комментарии:
1. Да, это лучшее, что я мог придумать, и, вероятно, нормально с прагматической точки зрения. Меня беспокоило то, что это нарушает «правило» (DDD), согласно которому вы должны обращаться к дочерним объектам путем обхода коллекций родительского (совокупного корневого) объекта, а не возврата в репозиторий (см. пункт a в вопросе)
2. Я бы не рассматривал прямой доступ к дочерним объектам как антишаблон DDD, однако я бы счел, что прямое обновление дочерних объектов недопустимо. Для обеспечения соблюдения инвариантов и других бизнес-правил необходимо задействовать aggregate root. Чтение и обновление сильно отличаются, и это одна из причин, почему CQRS популярен в сообществе DDD.
3. Спасибо @Michael — пища для размышлений. Я рад, что консенсус, похоже, прямолинейный. У меня нет опыта работы с концепцией CQRS, но я также рассмотрю это в какой-то момент.
Ответ №2:
Вы могли бы сопоставить OldestChild с помощью формулы. Взгляните на это, чтобы сопоставить класс с формулой: http://blog.khedan.com/2009/01/eager-loading-from-formula-in.html