ObjectStateManager in Entity Framework is responsible for tracking states and changes of an object. In this post let’s see how we can use ObjectStateManager to track object changes in following scenarios.
- Adding a new item
- Updating simple property of an existing item
- Updating complex property of an existing item
- Adding item to a collection type property of an existing item
- Removing item to a collection type property of an existing item
- Deleting an existing item
Let’s jump into action by creating a console application and installing Entity Framework nuget package (I am installing installing the latest as of today which is 6.1.2) the project. In this application, I am going create a code-first sample database with three POCO entity types which are “Department”, “Hobby” and “Person”. I am modeling the entities and their relationships as follows. I have two helper methods in "Department" and "Hobby" class to return some sample data.
Following is the class MyContext which is deriving from DbContext.
Now to create the database and to insert some data, let’s run the following.
Now when I run this, I can see my database created with all the data inserted.
Now let’s dive in to deep writing some code using the ObjectStateManager to detect changes once the changes has been made. For that I am creating a method which I am naming as DetectChanges and it will be accepting a parameter of type MyContext.
In this method, I will be writing the code to track changes. Now let’s start adding content to above method, first by making sure changes are synchronized with changes in all objects that are tracked by the ObjectStateManager.
After getting reference to current ObjectContexts’ ObjectStateManager, let’s proceed with getting different ObjectStateEntry’s which has different EntityStates’.
EntityState : Added
Now for each of this ObjectStateEntrys’, let’s see what are the changes. I am creating another method which I am naming as LogAddedEntries and passing the ObjectStateEntry as a parameter.Here the passing ObjectStateEntry can be of two types.
So inside my LogAddedEntries method I will have check if the added item is a relationship entity or a just a new entity.
If the added item is a RelationshipEntry, I am logging the names of two entities which gets into a relationship and by which items. If the added item is a EntityEntry, I am logging the name of the entity in which to the item is getting added and it’s details.
EntityState : Modified
Now same as Added changes, I am getting the ObjectStateEntrys’ in which the EntityState is Modified.
Now here is my method for logging modified entry details method which I am naming as LogModifiedEntries.
Here I am getting the modified properties and logging the original and current values of them.
EntityState : Deleted
Here is my method for logging deleted entry details method which I am naming as LogDeletedEntries.
Here again I need to check whether the deleted item is a relationship entity or a just a new entity. If the deleted item is a RelationshipEntry, I am logging the names of two entities which get unlinked and by which items. If the deleted item is a EntityEntry, I am logging the name of entity in which the item is getting deleted and it’s identifier.
Now I am almost done. For the demonstration purposes, let’s comment the above lines of codes and write some code to make some changes to existing data in the database. Before calling the context.SaveChanges(), let’s call the DetectChanges method to see what are the changes.
Adding a new item
Updating simple property of an existing item
Updating complex property of an existing item
Adding item to a collection type property of an existing item
Removing item to a collection type property of an existing item
Deleting an existing item
So that’s it. Finally following are list of some things, I think you will find important.
- Updating of complex property will does not falls to EntityState.Modified category. It will be removing of an existing relationship and adding of an new relationship.
- Added objects has no OriginalValues.
- Deleted objects has no CurrentValues.
Hope you all got a good understanding about ObjectStateManager and now you should be able to what you have learnt so far to match your requirements.
I am uploading the full sample to my OneDrive.