An Object with the same key already exists in the ObjectStateManager, Entity Frawework
I have a generic repository which I use in my application to manage a large number of objects. I wrote the necessary unit tests to ensure that all methods work as expected and in isolation all was good. However, as soon as the application started implementing more complex operations, I came across the following error during updates:
An object with the same key already exists in the ObjectStateManager. The ObjectStateManager cannot track multiple objects with the same key.”
In my controller I do something along these lines:
Nothing unusual here. Move on, nothing to see. I fetch the existing user object, update some values and send it to the repository to update the database. However, EF is not happy about the fact that I am trying to re-attach and update an object that is already placed in the cache. My repository code for the Update method is pretty simple:
I searched the web and mainly Stack Overflow and I found out that a few people have already come across this issue. The workaround, as suggested on StackOverflow here, is pretty straight forward, though not as easy if you are using a generic repository like me. The solution took a bit of time but it worked exactly as intended. The code for the generic Update method is attached below:
The important bit for this method to work is to be able to retrieve the id from any entity that needs to be updated in order to perform a Find(id). If an object with the same id already exist in the database, we retrieve it and copy the new values to it, otherwise, we attach to affected entity and then set it’s state to Modified in order for EF to perform the right action at Save() time. We use Reflection to retrieve the value in question. What this helper method does, is look into all the object properties and retrieve the one that has an attribute of Key. My data model objects all use data annotations and I have specified a custom key column instead of letting EF define one for me.
The code above works nicely both with attached and detached entities and allows you to code without worrying how to manage the updates.
P.S Make sure you follow me on Twitter @christosmatskas for more up-to-date news, articles and tips.