Представление Master-Detail в сочетании с шаблонами ORM, Unit of Work и Repository - PullRequest
3 голосов
/ 13 марта 2012

Я не уверен, как наилучшим образом реализовать представление основных деталей в сочетании с ORM.Приложение использует WPF с MVVM и отображает сетку всех доступных объектов, а также подробную информацию о выбранном в данный момент объекте.

ViewModel представления довольно прост, оно имеет:

  • An ObservableCollection<ItemViewModel> Items, где ItemViewModel - это ViewModel для объекта домена, который должен отображаться в представлении.Это свойство привязано к сетке.
  • A ItemViewModel CurrentItem свойство, которое привязано к сетке SelectedItem.
  • ICommand для «Добавить новый элемент», «Удалить выбранный элемент»и «Сохранить изменения в выбранном элементе».

Мое приложение использует NHibernate в качестве инструмента ORM, но я не хочу утекать NHibernate по всей базе кода, поэтому я абстрагировал его с помощью «Единицы работы»Шаблоны "и" Репозиторий ".

Специфическая реализация этих шаблонов в NHibernate такова, что" Единица работы "открывает новый сеанс NHibernate и транзакцию в начале и в конце фиксирует транзакцию и удаляет сеанс,Таким образом, время жизни единицы работы, сеанса и транзакции одинаково.Единица работы имеет свойство Repository, которое использует тот же сеанс, что и единица работы, а также имеет то же время жизни.

Вот где оно становится проблематичным: я хотел бы заполнить Items Коллекция в конструкторе MasterDetailViewModel.В настоящее время мне нужно создать новую единицу работы и заполнить коллекцию.Чтобы не иметь долго выполняющихся транзакций, UoW должен быть удален непосредственно после этого, удаляя также базовый сеанс.

Теперь, когда пользователь хочет сохранить изменения в текущем элементе, мне нужно будет открыть другой UoW, извлечьобъект из базы данных, обновите его текущими значениями ItemViewModel, сохраните его в базе данных и утилизируйте UoW.
Однако этот подход имеет несколько важных недостатков:

  1. Мой код замусорен using(var uow = uowFactory.StartNew()).
  2. Оптимистическая блокировка не выполняется.Если кто-то другой изменил бы тот же элемент в базе данных, его изменение было бы перезаписано.
  3. Для обновления элемента требуется два попадания в базу данных вместо одного.

Это приводитЯ пришел к выводу, что реализация моего UoW имеет недостатки.

Я думал об изменении реализации так, чтобы отношения между UoW и репозиторием были обратными.Это будет означать, что IoC внедрит репозиторий в ViewModel вместо UnitOfWorkFactory.Репозиторий теперь является функциональным эквивалентом ISession от NHibernate.Репозиторий может запустить новый UoW, который теперь идентичен транзакции базы данных.
Это хорошо подходит для моего сценария Master / Detail, но он не поддерживает понятие «бизнес-транзакции», которое обычно используется в качестве синонима.для единицы работы, например, логическая транзакция, охватывающая несколько транзакций базы данных и запрос пользователя.

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

1 Ответ

0 голосов
/ 14 марта 2012

Изменение места, где вы начинаете бизнес-транзакцию, не обязательно меняет ее гранулярность.

Не уверен, что я полностью понял ваш пример, но я не вижу, как запуск нового UoW в каждом из методов репозитория (каждый раз, когда он запрашивает постоянное хранилище) настолько отличается гранулярность, чем запуск нового UoW, когда MasterDetailViewModel заполняет свои элементы, а другой - каждый раз, когда один из элементов сохраняется.

Однако, как вы предлагаете, я будет вставлять репозиторий в саму ViewModel, поскольку для UoW кажется странным иметь свойство Repository - UoW не манипулирует Repository напрямую, это скорее какой-то объект который использует репозиторий в контексте UoW.

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

Хотя есть много других сессионных стратегий. Вы найдете некоторые предложения в этой статье .

Также см.

Какова ваша стратегия управления сессиями для NHibernate в настольных приложениях?

Каким должно быть время жизни сеанса NHibernate?

...