Шаблон NHibernate для логически связанных объектов без повсеместной передачи ISession

Предположим, у меня есть класс с именем «Клиент», и имеет смысл иметь в классе такой метод, как:

void AddOrder(Item item, int quantity, decimal pricePerUnit)

Метод AddOrder концептуально создает новые записи в базе данных.

С точки зрения C # проблем с подписью метода выше нет, но для целей NHibernate он должен иметь доступ к ISession для сохранения новых объектов в базе данных.

Каков подходящий шаблон для достижения этого, не заставляя каждый метод в моих постоянных классах иметь параметр ISession?

Должен ли я унаследовать свои постоянные классы от общего абстрактного предка, который получает текущий экземпляр ISession с помощью внедрения зависимостей? (т.е. реализовать тонкую оболочку для ISession, которая действует как фабрика объектов, которая обрабатывает все запросы на создание или выборку)

Есть ли для этого хороший образец?

PS - Я знаю, что не хочу использовать шаблон репозитория. Это слишком произвольная форма для очень сложной модели данных.


Уточнение:

Рассматриваемая модель данных представляет собой систему бухгалтерского учета с двойной записью. Большинство разработчиков ничего не знают о механике двойного входа и не хотят этого. Итак, что я хотел бы сделать, так это предоставить методы кода, которые указывают разработчику «Что я могу сделать с этим объектом?», а не использовать только свойства, что является обычным способом NHibernate.

Я использовал NHibernate сейчас для изрядного количества проектов и постоянно возвращаюсь к выводу, что мне действительно следует поместить все взаимодействия с данными для очень сложных систем за высокоструктурированный API и единственные люди, которые работают над серверной частью. этого API должны быть экспертами по модели данных / сохраняемости. Программисты, которые просто взаимодействуют с данными, просто знают, как использовать API. Это не тот вывод, который я действительно хочу сделать, поскольку это приведет к значительным накладным расходам на разработку в некоторые из наших систем. (Конечно, это путь к сервис-ориентированной архитектуре, и в наши дни он может быть «данностью» для крупных проектов)


person David Montgomery    schedule 18.11.2014    source источник
comment
Вы сводите на нет многие преимущества, которые дает использование O / RM, заставляя все изменения немедленно сохраняться в базе данных. Не могли бы вы прояснить еще немного? Я был бы немного обеспокоен вашей объектной моделью, если вы считаете, что NHibernate слишком сложно справиться с ней, не изобретая колесо.   -  person Michael    schedule 18.11.2014
comment
@Michael Когда вызывается ISession.Save (), меня не беспокоит. Меня больше беспокоит то, как разработчики взаимодействуют с моделью персистентности в своем коде без необходимости становиться экспертами по маленьким «частям и частям». Добавляем пример выше для пояснения.   -  person David Montgomery    schedule 19.11.2014


Ответы (1)


Если Customer является постоянным классом, вам не нужно будет обращаться к объекту сеанса, чтобы добавить новую запись Item. Заказчику необходимо иметь свойство коллекции Items, отображаемое как ассоциацию «имеет многие или многие-ко-многим» с параметром каскадного сопоставления, установленным на «сохранить» или «все».

Метод AddItem() должен просто добавить экземпляр Item в коллекцию Items объекта Customer. После того, как вы зафиксируете транзакцию NHibernate (обычно это делается в фильтре действий, http-модуле или каком-либо другом классе инфраструктуры), NHibernate сохранит все записи.

Если Customer - это новый экземпляр класса, вам нужно будет вызвать метод Save текущего экземпляра ISession. Вам также придется вызвать метод Remove, чтобы удалить постоянный объект.

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

Изменить: похоже, вы хотите, чтобы объекты сохранялись сразу. Я бы рекомендовал сделать транзакции короткими, а не ссылаться на сеанс и очищать его вручную. Хотя это возможно сделать позже правильно, обычно вы отрицаете многие преимущества целостности данных ORM.

person Dmitry S.    schedule 18.11.2014
comment
Я считаю, что вы правы, что отображение - единственный способ. - person David Montgomery; 26.11.2014