Единица работы, варианты отката - PullRequest
5 голосов
/ 10 февраля 2011

Я пытаюсь создать систему, которая следует хранилищу и шаблонам рабочих единиц, чтобы обеспечить постоянное невежество / модульное тестирование и т. Д. И т. Д. Я ищу совет по работе с Rollback.В идеале я хочу использовать POCO, но я думаю, что мне может понадобиться, по крайней мере, реализовать интерфейс для обеспечения нескольких кусочков.

Итак, допустим, у нас есть два хранилища, один контекст / единица работы.

Я добавляю один элемент, изменяю другой элемент и удаляю третий элемент.Повторите для второго репозитория, затем я вызываю откат.

В прошлом я использовал для этого что-то похожее на DataSet.Каждый объект имеет состояние pendingNew, pendingAeded, pendingDeleted, clean.Существует также копия последней сохраненной версии объекта для отката.

Как бы вы это реализовали?

РЕДАКТИРОВАТЬ:

Хорошо, вот что я думаю, что я на самом деле пытаюсь разобраться.Приготовьтесь к шаблону:)

В конечном итоге проект - WPF MVVM.Итак, мы смотрим на модель на то, что магазин находится здесь.

Я думаю, что я пытался связать модель с идеей хранилища, где, как я думаю, модель должна использовать UOW иРепозитории для предоставления функций, которые должна предоставлять модель.Звучит лучше?

Я хочу полного невежества, поэтому представьте, что мой домен включает в себя Customer, Order и OrderLines.

Скажем, в графическом интерфейсе есть новая кнопка, позволяющая пользователю заполнить данные о клиенте, сведения о заказе и 1-n детали OrderLine.Он нажимает «Сохранить», и они переходят в базу данных, он нажимает «Отмена».

Таким образом, в этом случае модель может запросить у клиента CustomerRepository, затем OrderRepository для нового Order, затем OrderLineRepositoryдля каждой новой строки, затем скажите единице работы, чтобы сохранить их.

Это звучит разумно?Это касается меня, я думаю, что именно здесь определено разделение.Я наполовину соблазн иметь другой API между моделью и репозиториями.Нет, это глупо.

РЕДАКТИРОВАТЬ 2: Это отличная статья, которая вроде немного помогла .

Ответы [ 3 ]

6 голосов
/ 10 февраля 2011

Я разработал свою единицу работы и классы репозитория аналогично тому, как это описано здесь, в MSDN .Основная идея класса IUnitOfWork заключается в том, что он обрабатывает всю работу с базой данных.

Затем я добавил (к моему классу IUnitOfWork и реализациям) метод BeginTransaction(), который открывает TransactionScope()объект, а затем добавил метод EndTransaction(bool commit).Этот метод обрабатывает закрытие транзакции, либо фиксируя транзакцию в базе данных (если true), либо откатывая транзакцию (если false).

Это позволяет мне контролировать сложные транзакции, позволяя откатывать несколько коммитов.,

Редактировать: Моя точка зрения заключается в том, что вы хотите, чтобы ваш объект UnitOfWork знал о репозиториях, а не наоборот.Это мое мнение, и вы найдете людей, которым нравится обратное, но вот почему.

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

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

Наконец, сохранение доступа к вашим репозиториям как доступного только через ваши единицы работы делает API-интерфейс простым для разработчиков.Для начала вам нужно всего лишь создать 1 объект (единицу работы) вместо 1 единицы рабочего объекта плюс столько объектов репозитория, которые вам могут понадобиться.Это делает ваш код простым (imho) и делает вещи менее подверженными ошибкам для разработчиков.

2 голосов
/ 10 февраля 2011

Трудно сказать наверняка без более подробной информации, но я бы посмотрел на реализацию из интерфейса IDbConnection и связанных интерфейсов. Он дает вам интерфейс, с которым большинство C # -кодировщиков знакомо.

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

0 голосов
/ 10 февраля 2011

Я бы реализовал это, используя для этого такую ​​среду, как NHibernate или Entity Framework. :) NHibernate позволяет вам использовать POCO и выполняет всю сантехнику за вас.

...