Реализация отслеживания изменений объектов в приложении WCF MVC N-уровня

большинство примеров, которые я видел в интернете, показывают отслеживание изменений объекта в контексте WinForms/WPF. Или если он находится в интернете, используются подключенные объекты, поэтому изменения, внесенные в каждый объект, можно отслеживать.

в моем сценарии объекты отключаются, как только они покидают уровень данных (сопоставляются с бизнес-объектами в WCF и сопоставляются с DTO в приложении MVC)

когда пользователи вносят изменения в объект на MVC (например, изменение свойства поля 1), как это сделать Я отправляю это изменение из представления, вплоть до DB?

Я хотел бы иметь таблицу аудита, которая сохраняет изменения, внесенные в конкретный объект. Я хотел бы сохранить значения before & after объекта только для свойств, которые мы изменили

Я могу придумать несколько способов сделать это

1) реализовать флаг IsDirty для каждого свойства для всех моделей в слое MVC (или в javascript?). Распространяйте эту информацию до конца. вплоть до уровня сервиса и, наконец, до уровня данных.

2) Наличие этого механизма отслеживания изменений в слое обслуживания было бы здорово, но как я буду отслеживать "исходные" значения после того, как измененные значения были переданы из MVC?

3) триггеры базы данных? Но я не знаю, с чего начать. Это вообще возможно?

существуют ли какие-либо известные реализации отслеживания изменений объектов для n-уровневого mvc-wcf решение?

пример таблицы для проверки:

Audit table

Id              Object         Property         OldValue                NewValue
--------------------------------------------------------------------------------------
1               Customer       Name             Bob                     Joe
2               Customer       Age              21                      22

2 ответов


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

в других словах, как только он" выходит " из базы данных, он заблокирован исключительно для пользователя или может другие пользователи или процессы обновлять его в то же время?

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

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

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

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

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

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

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


есть две части вашего вопроса:

  1. как это сделать в MVC:

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

  1. как это сделать в базе данных: Это, вероятно, ваш предполагаемый вопрос:

прежде всего держитесь подальше от рамок ORM, жизнь слишком сложна, как это.

на последнем шаге операции сохранения вы должны иметь следующую информацию:

  • объекты и поля, которые необходимо изменить, и их новые значения.

вам нужно отслеживать следующее информация:

  • какое последнее изменение объекта вы собираетесь изменить в базе данных.

Это может быть получено из таблицы аудита и должно быть сохранено в сеансе (или сеансе как объект).

тогда вам нужно сделать следующее В транзакции:

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

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