I am curious how people are actually tracking changes in data entry applications. Either if it is for keeping history of which users has changed what etc or for handling concurrency issues. For both scenarios you need to knwo what the user has changed and
I have not yet seen a good method (read not requiring a lot of code).
Some might say "That is easy. When you save just compare current values with what is in database". Yes, in most cases it would be true but it might also be that data has been changed by some other user and you don't know if your current values are current
and changed by the user or stale. However in some cases it might the right thing to do. You can argue that when the user press "save/submit" he actually say that "these are the values which I want to save" not matter that any other user has changed any field.
But that is very application specific.
The only safe method as I see it is to compare the current values with the inital values when user first started to edit data. However the traditional way to do this is to use hidden fields with your initial values. Also it would require more data to be
sent from server to client.
One solution perhaps is if those hidden fields (or serialized as json) could be generated with javascript on initial load.
Are there any plugins/frameworks to help with this? It should be quite a common need I think. However most web based data entry applications are actually just saving what the user submits and overwrite what is in the database.
Interested to hear how you solve problems like this. I don't have a specific need for this right now so more looking for a generic solution and discussion.
It really all depends on which data access technology you are using. For example Entity Framework has change tracking built in to the framework so that you don't have to keep track of changes and it will figure out what has changed in your entity and do
the updates for you.
If you are writing inline sql or using stored procedures then I wouldn't use hidden fields for this. Instead I would craft my sql query to only update the fields that the user has access to. It's important to note that a stored procedure would be better
for this because you can wrap the entire operation in a transaction. If you need further control you can always enfore locks in code but that will have a major impact on your applications performance.
It really all depends on which data access technology you are using. For example Entity Framework has change tracking built in to the framework so that you don't have to keep track of changes and it will figure out what has changed in your entity and do the
updates for you.
EF has change tracking yes but only as long as your using the same objectcontext. How would you maintain objectcontext between when you are first rendering initial view and get it back on post? Model data is created as a new object from posted form data.
Maybe if you were able to serialize the original object in some way.
CodeHobo
If you are writing inline sql or using stored procedures then I wouldn't use hidden fields for this. Instead I would craft my sql query to only update the fields that the user has access to.
Not sure how you mean. If you mean that you should update only those colums which are actually used in the page then yes. For example if one user update credit limit in one page and another user address in another page for same custonmer then you should
only update credit limit for first user and address for second user. But that is not really the problem I am thinking of. Let say you have a page to edit customer. How would you know that a user only has changed for example the address without comparing with
original data?
EF has change tracking yes but only as long as your using the same objectcontext. How would you maintain objectcontext between when you are first rendering initial view and get it back on post? Model data is created as a new
object from posted form data. Maybe if you were able to serialize the original object in some way.
Well I generally do in my applications is that in the post action I query the objectcontext for the entity I want (by id for example) and then apply the changes to that model either by using updatemodel , automapper or manually
doing assignments. In this case the changes are applied and the object context knows how to update the database table accordingly.
magnusb999
Not sure how you mean. If you mean that you should update only those colums which are actually used in the page then yes. For example if one user update credit limit in one page and another user address in another page for same
custonmer then you should only update credit limit for first user and address for second user. But that is not really the problem I am thinking of. Let say you have a page to edit customer. How would you know that a user only has changed for example the address
without comparing with original data?
Well I'm thinking if the screen is an edit screen for address, then you always update the data with whatever data came over for address. So you populate the screen with initial data and upon submitting the form always save the
data. There is no need to figure out what changed, just assume that whatever came from the user is the most up to date information.
Let say you have a page to edit customer. How would you know that a user only has changed for example the address without comparing with original data?
If you plan to track the changes then you can always spin up the Table_Audit tables (traditional approach) with additional field to track the Inser/Update/Delete operation and user who updated the data with IPAddress or any other details if you like.
If you plan to compare agains the data which was saved after the user retrieved it, then its better to have a timestamp field in db which can be used to compare to know if data has been updated after user retrieved it.
Well I generally do in my applications is that in the post action I query the objectcontext for the entity I want (by id for example) and then apply the changes to that model either by using updatemodel , automapper or manually doing assignments. In this case
the changes are applied and the object context knows how to update the database table accordingly.
Ok now I understand. I thought you meant it would track the changes from when the user started to edit. Yes true that would only update the columns you have changed. However, if for example your view has field1, field2 and field3 they would all be updated
even if the user has only changed field3. There is no way to tell that the user has only chnaged field3 (without having stored the original values).
CodeHobo
Well I'm thinking if the screen is an edit screen for address, then you always update the data with whatever data came over for address. So you populate the screen with initial data and upon submitting the form always save the data. There is no need to figure
out what changed, just assume that whatever came from the user is the most up to date information.
Let say customer calls to change invoice address. User John take the call and start to enter the information but get interrupted and don't save the changes. Customer calls again because he forgot to say that phone number has changed as well. user Dave change
the phone number and saving that into db. Some minuts later John return and realized he didnt save the customer's adress data (still on screen). Phone number in database will be overwritten with the old phone number.
If the application had tracked what he really has changed it would only have updated the invoice address.
Not a very good example maybe. In reality it is not that often a problem.
Changes Tracking cannot be accomplidhed jut with the help of EF. You can use the tehnique sketched by @codehobo just if you already know you are processing an entity modification. Therefore as a first step you have to classify insert/modifications/delete....this
is the difficult part and there are several techniques to achive this result: 1) javascript preprocessing of a clkent viewmodel to send to the server just the changes. The javascript updates manager of the Mvc Controls Toolkit use this techniques. 2) Rendering
for each item also the old unmodified item in json into an hidden field. This way when you dont receive the old item you have an insert, when you receive no modified entity you have a delete, etc. This technique is used by the DatagridFor helper of the Mvc
Controls Toolkit. 3) Comparing the Viemodel received by the server agains an hold copy stored in the session dictionary o serialized in json into an hidden field. The algorithm uses a recursive procedure and reflection. An im9lementation is contained in the
Data Moving Plugin of the Mvc Controls Toolkit 4) Avoiding to process complex models and to have separate action methods for modifications, delete and insert operations. This way when you receive the web request you already know the unique operation to be
performed: modification, insert, delete
Changes Tracking cannot be accomplidhed jut with the help of EF.
Yes I know. Think I will take a look at MVC control kit. Even if my current project does not really need it I am intresting to find a solution for future projects.
magnusb999
Member
23 Points
55 Posts
Tracking changes
Feb 26, 2013 07:44 PM|LINK
I am curious how people are actually tracking changes in data entry applications. Either if it is for keeping history of which users has changed what etc or for handling concurrency issues. For both scenarios you need to knwo what the user has changed and I have not yet seen a good method (read not requiring a lot of code).
Some might say "That is easy. When you save just compare current values with what is in database". Yes, in most cases it would be true but it might also be that data has been changed by some other user and you don't know if your current values are current and changed by the user or stale. However in some cases it might the right thing to do. You can argue that when the user press "save/submit" he actually say that "these are the values which I want to save" not matter that any other user has changed any field. But that is very application specific.
The only safe method as I see it is to compare the current values with the inital values when user first started to edit data. However the traditional way to do this is to use hidden fields with your initial values. Also it would require more data to be sent from server to client.
One solution perhaps is if those hidden fields (or serialized as json) could be generated with javascript on initial load.
Are there any plugins/frameworks to help with this? It should be quite a common need I think. However most web based data entry applications are actually just saving what the user submits and overwrite what is in the database.
Interested to hear how you solve problems like this. I don't have a specific need for this right now so more looking for a generic solution and discussion.
CodeHobo
All-Star
18647 Points
2647 Posts
Re: Tracking changes
Feb 26, 2013 08:13 PM|LINK
It really all depends on which data access technology you are using. For example Entity Framework has change tracking built in to the framework so that you don't have to keep track of changes and it will figure out what has changed in your entity and do the updates for you.
If you are writing inline sql or using stored procedures then I wouldn't use hidden fields for this. Instead I would craft my sql query to only update the fields that the user has access to. It's important to note that a stored procedure would be better for this because you can wrap the entire operation in a transaction. If you need further control you can always enfore locks in code but that will have a major impact on your applications performance.
Blog | Twitter : @Hattan
magnusb999
Member
23 Points
55 Posts
Re: Tracking changes
Feb 26, 2013 08:36 PM|LINK
EF has change tracking yes but only as long as your using the same objectcontext. How would you maintain objectcontext between when you are first rendering initial view and get it back on post? Model data is created as a new object from posted form data. Maybe if you were able to serialize the original object in some way.
Not sure how you mean. If you mean that you should update only those colums which are actually used in the page then yes. For example if one user update credit limit in one page and another user address in another page for same custonmer then you should only update credit limit for first user and address for second user. But that is not really the problem I am thinking of. Let say you have a page to edit customer. How would you know that a user only has changed for example the address without comparing with original data?
CodeHobo
All-Star
18647 Points
2647 Posts
Re: Tracking changes
Feb 26, 2013 09:34 PM|LINK
Well I generally do in my applications is that in the post action I query the objectcontext for the entity I want (by id for example) and then apply the changes to that model either by using updatemodel , automapper or manually doing assignments. In this case the changes are applied and the object context knows how to update the database table accordingly.
Well I'm thinking if the screen is an edit screen for address, then you always update the data with whatever data came over for address. So you populate the screen with initial data and upon submitting the form always save the data. There is no need to figure out what changed, just assume that whatever came from the user is the most up to date information.
Blog | Twitter : @Hattan
CPrakash82
All-Star
18154 Points
2831 Posts
Re: Tracking changes
Feb 26, 2013 09:45 PM|LINK
If you plan to track the changes then you can always spin up the Table_Audit tables (traditional approach) with additional field to track the Inser/Update/Delete operation and user who updated the data with IPAddress or any other details if you like.
If you plan to compare agains the data which was saved after the user retrieved it, then its better to have a timestamp field in db which can be used to compare to know if data has been updated after user retrieved it.
magnusb999
Member
23 Points
55 Posts
Re: Tracking changes
Feb 26, 2013 10:44 PM|LINK
Ok now I understand. I thought you meant it would track the changes from when the user started to edit. Yes true that would only update the columns you have changed. However, if for example your view has field1, field2 and field3 they would all be updated even if the user has only changed field3. There is no way to tell that the user has only chnaged field3 (without having stored the original values).
Let say customer calls to change invoice address. User John take the call and start to enter the information but get interrupted and don't save the changes. Customer calls again because he forgot to say that phone number has changed as well. user Dave change the phone number and saving that into db. Some minuts later John return and realized he didnt save the customer's adress data (still on screen). Phone number in database will be overwritten with the old phone number.
If the application had tracked what he really has changed it would only have updated the invoice address.
Not a very good example maybe. In reality it is not that often a problem.
francesco ab...
All-Star
20888 Points
3277 Posts
Re: Tracking changes
Feb 26, 2013 10:46 PM|LINK
Mvc Controls Toolkit | Data Moving Plug-in Videos
magnusb999
Member
23 Points
55 Posts
Re: Tracking changes
Feb 26, 2013 10:56 PM|LINK
Yes I know. Think I will take a look at MVC control kit. Even if my current project does not really need it I am intresting to find a solution for future projects.