Кэширование вычисленных значений (Суммы / Итоги) в Базе данных - PullRequest
0 голосов
/ 27 августа 2009

Рассмотрим следующую объектную модель (- >> обозначает коллекцию):

Клиент-> Заказы

Заказы - >> OrderLineItems-> Product {} Цена

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

Если подумать об этом, также может быть несколько платежей (банковские переводы, чеки, кредитные карты и т. Д.), Связанных с каждым заказом, опять же, меня интересует только сумма денег, которую я получил.

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

Моя идея заключалась в том, чтобы сохранить привязку каждого заказа к объекту «статус», кэшируя все суммы и статус заказа, улучшая производительность запросов на порядки, а также поддерживая сценарии запросов для неоплаченных заказов, оплаченных заказов, причитающихся заказов и т.д.

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

До сих пор я использовал Observable Collections, которые запускают пересчеты Status, когда элементы добавляются или удаляются, или обновляются определенные свойства элементов. Я спрашиваю себя, где логика для всего, что должно быть поставлено с точки зрения DDD. Мне кажется странным заставить всю логику обработки событий и вычислений в совокупном корне.

Ответы [ 3 ]

1 голос
/ 04 сентября 2009

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

Кроме того, ваш DAL может разумно выбирать, какую стратегию выборки применять из интерфейса, который вы запрашиваете, то есть ленивую загрузку в ситуациях, когда вам не нужен доступ к дочерним объектам, и нетерпеливую загрузку, где вы делаете.

Уди Дахан имеет замечательных постов в блоге об этом . Он написал и рассказал о применении интерфейсов, раскрывающих намерения, к этой проблеме, которую он называет , делая роли явными .

0 голосов
/ 16 сентября 2009

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

Обычно это вызов «Сервиса».

0 голосов
/ 27 августа 2009

Я настоятельно рекомендую изучить OR (объектно-реляционные) средства отображения, которые поддерживают LINQ. Чтобы назвать два основных, LINQ to SQL и Entity Framework, оба от Microsoft. Я считаю, что LLBLGen теперь также поддерживает LINQ, и в nHibernate есть несколько полуобработанных решений LINQ, которые вы можете попробовать. Моя основная рекомендация - Entity Framework v4.0, которая доступна в бета-версиях .NET 4.0 или в бета-версии Visual Studio 2010.

С помощью LINQ OR, вы можете легко запрашивать сводную информацию, которая вам нужна, динамически, в режиме реального времени, используя только модель вашего домена. Нет необходимости просачиваться бизнес-логика на уровень данных, потому что вы обычно не будете использовать хранимые процедуры. ИЛИ мапперы генерируют параметризованный SQL для вас на лету. LINQ в сочетании с OR mappers является чрезвычайно мощным инструментом, который позволяет вам не только запрашивать и извлекать сущности и графы сущностей, но также запрашивать проекции данных в вашей доменной модели ... позволяя извлекать пользовательские наборы данных, агрегаты и т.д. через единую концептуальную модель.

...