Implementing object change tracking in the MVC N-Tier application

Most of the examples that I saw on the Internet show tracking changes in objects in the context of WinForms / WPF. Or, if it is used on a network, related objects are used, so changes made to each object can be tracked.

In my scenario, objects are disabled after they leave the data layer (mapped to business objects in WCF and displayed in DTO in the MVC application)

When users make changes to an object in MVC (for example, by changing a property of a field), how can I send this change from a view, right down to the database?

I would like to have an audit table that saves the changes made to a specific object. I would like to save the values ​​before and after the values ​​only for the properties that we modified

I can come up with several ways to do this.

1) Enter the IsDirty flag for each property for all models at the MVC level (or in javascript?). Spread this information right down to the service level and finally the data layer.

2) Having this mechanism for tracking changes in the service level would be great, but how would I then track the “original” values ​​after the changed values ​​were returned from MVC?

3) Database triggers? But I'm not sure how to get started. Is it possible?

Are there any known object change tracking implementations for n-level mvc-wcf solution?

Example audit table:

Audit table Id Object Property OldValue NewValue -------------------------------------------------------------------------------------- 1 Customer Name Bob Joe 2 Customer Age 21 22 
+6
source share
2 answers

Possible solutions to this problem will largely depend on what changes you allow in the database while the user is editing the data.

In other words, as soon as it “leaves” the database, it is blocked exclusively for the user, or can other users or processes update it during this time?

For example, if a user can receive data and sit on it for several hours or days, but the database continues to allow data updates, then you really want to track the changes made by the user to the database currently, and not the changes made by the user to The data they are viewing.

The way we process this scenario is to start a transaction, read the entire existing object, and then use reflection to compare old and new values, recording the changes in the audit log. This gets a little complicated when working with nested records, but it’s worth the time.

If, on the other hand, other users or processes are not allowed to modify the data, then you have several different parameters that vary in complexity, data storage and impact on existing data structures.

For example, you can change each property in each of your classes to record when it has changed, and save the current evaluation of these changes in the class (obviously, implementing a base class helps a lot here).

However, depending on the point at which you commit user changes (each time they update a field in a form, for example), this can generate a significant amount of irreplaceable log information, because you probably only want to know what has changed in terms of databases, not in terms of user interface.

You can also deeply clone an object and transfer it around layers. Then, when it is time to determine what has changed, you can use reflection again. However, depending on the size of your business objects, this approach may impose a hefty execution penalty, since the full copy must be moved along the wire and saved with the original record.

You can also implement the same approach as the "Updates allowed during editing" approach. This, in my opinion, is the purest solution, because the source data should not move with the edited data, there is no way to fake the source data and supports many clients without supporting tracking changes in the user interface level.

+3
source

There are two parts to your question:

  • How to do it in MVC:

The usual way: you send the changes back to the server, the controller processes them, etc. etc. In your use case, there is nothing unusual that requires a change in the way MVC works. It’s better for the scenario of your use for changes that should be encoded as separate changes operations, and not as a changed object, you had to use reflection to find out what changes the user made.

  • How to do it in the database: This is probably your intended question:

First of all, stay away from ORM structures, life is too complicated.

In the last step of the save operation, you should get the following information:

  • Objects and fields that need to be changed, and their new values.

You need to track the following information:

  • The last change to the object you want to change in the database.

This can be obtained from the audit table and must be saved in the session (or in the session as an object).

Then you need to do the following in the transaction:

  • Get the latest change to the object (s) that will be modified from the database.
  • If the objects are changed aborted and notify the user of a collision.
  • If you do not get the current values ​​of the fields to be changed.
  • Save the new values.
  • Update audit table.

I would use a stored procedure to do this, to make the process less conversational, and to further separate problems between the database code and the application code.

0
source

Source: https://habr.com/ru/post/949958/


All Articles