Data Platform Developer Center >
Data Platform Development Forums
>
ADO.NET Entity Framework and LINQ to Entities
>
InvalidOperationException on ObjectContext.AcceptAllChanges
InvalidOperationException on ObjectContext.AcceptAllChanges
- Hi,
I am encountering an InvalidOperationException from a call to ObjectContext.AcceptAllChanges().
The sequence of steps in the code is:
1. Create/Update some entities
2. Start a new EntityTransaction on the EntityConnection
3. Call ObjectContext.SaveChanges(false)
4. Do some GetObjectByKey/Linq queries (for logging purposes)
5. Call ObjectContext.AcceptAllChanges() --> throws InvalidOperationException
...
Exception Info
Message
"AcceptChanges cannot continue because the object's key values conflict with another object in the ObjectStateManager. Make sure that the key values are unique before calling AcceptChanges."
Source
"System.Data.Entity"
Stack Trace
at System.Data.Objects.ObjectStateManager.FixupKey(EntityEntry entry)
at System.Data.Objects.ObjectStateEntry.AcceptChanges()
at System.Data.Objects.ObjectContext.AcceptAllChanges()
at MyEntityModel.EntityContext.Save() in
Data
Empty - Data {System.Collections.ListDictionaryInternal} System.Collections.IDictionary {System.Collections.ListDictionaryInternal}
If I remove step 4, then the ObjectContext.AcceptAllChanges() executes successfully with no exception.
Since the Data property is empty, I cannot tell which entities are causing the problem.
So, my question is:
Is my code that invokes GetObjectByKey/Linq queries in step 4 expected to cause an exception in AcceptAllChanges() so I should restructure my code
or
is this exception unexpected indicating that there is something I am doing in step 4 that is invalid in this situation and that if I can avoid the invalid operation, then my code should work ?
Thanks in advance
Graham
Answers
- Well, if your LINQ queries in step 4 retrieve one or more of the entities that were new this session and saved to the database in step 3, then you have a problem. Entities which are in the added state have temporary EntityKeys which means that no query will identity resolve to them. In your case, because you do SaveChanges(false), the new entities are saved to the DB but kept in the added state. So your queries can cause an additional copy of the same entity to end up in the ObjectStateManager. Then, when the call is made to AcceptAllChanges, the system does an AcceptChanges on the new entity which turns its key from a temp key to a real one that conflicts with the key on the extra copy of that entity.
The workaround I'd recommend is to use NoTracking for your linq queries so that you can accomplish the logging without adding other copies of the entities to the context.
- Danny
This posting is provided "AS IS" with no warranties, and confers no rights.- Marked As Answer byGraham Hay Wednesday, July 01, 2009 9:38 AM
All Replies
- Well, if your LINQ queries in step 4 retrieve one or more of the entities that were new this session and saved to the database in step 3, then you have a problem. Entities which are in the added state have temporary EntityKeys which means that no query will identity resolve to them. In your case, because you do SaveChanges(false), the new entities are saved to the DB but kept in the added state. So your queries can cause an additional copy of the same entity to end up in the ObjectStateManager. Then, when the call is made to AcceptAllChanges, the system does an AcceptChanges on the new entity which turns its key from a temp key to a real one that conflicts with the key on the extra copy of that entity.
The workaround I'd recommend is to use NoTracking for your linq queries so that you can accomplish the logging without adding other copies of the entities to the context.
- Danny
This posting is provided "AS IS" with no warranties, and confers no rights.- Marked As Answer byGraham Hay Wednesday, July 01, 2009 9:38 AM
Hi Danny,
armed with your very clear explanation, I have restructured my code and I am now able to avoid the problem.
Thanks for your help
Graham
- Hi.I have the same problem using savechanges() method. The first time works, from the second time show the error Can you help me?
- Is it really the same as above? That is, are you calling SaveChanges(false) and then calling AcceptAllChanges() or is it something else where you are calling SaveChanges() twice? Also, what exactly is the exception message (which exception type and what message)?
- Danny
This posting is provided "AS IS" with no warranties, and confers no rights. - Daniel, this is my problem:----------------------------I use VS2008 SP1 and .NET 3.5.I have created an EF model from an existing DB with only one table like the following:ID INTEGERCODE VARCHARDESCRIPTION VARCHARThis table has an ID (primary key) with a trigger that autogenerate his values.I have bind this table to a gridview.After every insert,change or delete row, I call the savechanges method to save data.But I have this problem.The first time I insert a row, all works fine.The next times, the savechanges method raise the exception:InvalidOperationExceptionand if I go on, the last row is saved but also the previous rows are saved again.So, using the grid, if I insert the rows with this value:CODE DESCRIPTION1 12 23 34 45 5in the table I have:ID CODE DESCRIPTION1 1 12 2 23 2 25 2 29 2 24 3 36 3 38 3 37 4 411 4 410 5 5Finally, the ID is generated correctly but the rows are duplicated.Please, help me.Regards.Angelo.


