Подтвердить что ты не робот

Как реализовано разделение командной строки (CQS) при использовании ORM?

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

Если вы используете ORM (NHibernate в моем случае), то ясно, что ORM используется при выдаче команд. Но как насчет всех различных запросов, которые нужно выполнить для формирования данных (DTO) для пользовательских экранов, является ли обычной практикой прерывать ORM при выполнении Query-стороны CQS?

Где я должен выполнять свои запросы и проекции DTO? Прямой ADO.NET(datareaders, dtos, datatables, хранимые процедуры)? Некоторые запросы совершенно уникальны и связаны с множеством попыток собрать все вместе. Я не хочу денормализовать базу данных для запросов, но я мог бы создавать представления (денормализация плохого человека).

4b9b3361

Ответ 1

Я предполагаю, что CQS означает архитектурный шаблон DDD aka CQRS, а не строго традиционный Принцип CQS.

Я бы по-прежнему использовал NHibernate для вашей модели только для чтения. Есть много преимуществ, таких как будущие и многопроцессорные запросы, ленивая загрузка/загрузка и т.д., Которые будут оптимизировать работу БД. Кроме того, будет проще составлять запросы с ORM, если пользовательский интерфейс позволяет пользователю существенно изменить предложение where.

Относительно того, как технически обрабатывать модель только для чтения, вы можете пометить сущность immutable с помощью NHibernate. Вы могли бы просто пометить все ваши прочитанные объекты модели неизменяемыми. Кроме того, я не думаю, что вы можете обновлять прогнозы в NHibernate, так что это еще один вариант для вашей модели только для чтения (кто-то, пожалуйста, поправьте меня, если я ошибаюсь, поскольку я не уверен на 100%).

Относительно уродливых или невозможных NH-отображений: NH может отображать представления и хранимые процедуры, поэтому я думаю, что было бы хорошо использовать их, когда вам нужно. Представления, вероятно, немного более гибкие, чем хранимые процедуры для сценария только для чтения, потому что ваш SQL будет по-прежнему динамическим. Однако, если вам нужно читать/писать для любой из этих сплющенных структур, я бы привязал к процедуре магазина.

Ответ 2

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

Но NHibernate все еще может быть хорошим вариантом... он больше не является автоматическим значением по умолчанию (которое иногда используется для команды).

Мы решили использовать Castle Active Record (основанный на NHibernate под капотом), главным образом потому, что у него есть хорошая функция, которая будет генерировать таблицу для вас из класса. Это отлично подходит для нас, потому что здесь наш рабочий процесс: во-первых, мы создаем класс ViewModel. Этот класс полностью сформирован для нужд View. Затем мы отмечаем, что ViewModel с атрибутами Active Record Castle. Затем мы запрашиваем Active Record для создания соответствующей таблицы для этого класса в базе данных Query. Это самый быстрый, самый быстрый способ, с помощью которого мы быстро получили таблицу базы данных запросов, которая служит классу ViewModel. Автоматическое генерирование отражает реальность, что единственная причина, по которой существует таблица, заключается в обслуживании представления.

Ответ 3

Мы используем EF для командной части и прямые ADO.NET = > DTO для цепочки запросов. Преимущества:

1) Возможность оптимизировать SQL-запросы и использовать расширенные функции хранилища DB, не отнесенные к слою ORM

2) Меньше накладных расходов

Но мы используем разделение только для требовательных частей (поиск), остальные полагаются на общую модель Entity Framework.

Ответ 4

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

Вы все еще можете использовать NHibernate для чтения из своего хранилища данных, но вы можете сделать это очевидным, создав два разных класса для инкапсуляции доступа к данным. У одного класса были бы методы чтения (запроса) хранилища данных, у другого класса были бы методы выдачи команд (добавить, обновить, удалить) в хранилище данных.

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

Ответ 5

Мне нравится держать ORM отдельно для чтения и записи, поэтому я буду использовать (и я использую):

Nhibernate для команд - красиво отображает мою модель домена

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

Они идеальная пара, как Хан Соло и Чубакка.