3

I'm trying to solve an issue with the optimistic concurrency control on EF 6. I currently want to catch the DBUpdateConcurrencyException and then refresh the entity. However I am currently getting this Exception:

System.InvalidOperationException: The element at index 0 in the collection of objects to refresh has a null EntityKey property value or is not attached to this ObjectStateManager.

Here is a simplified version of the code that shows the purpose:

using (var dbContextTransaction = dbContext.Database.BeginTransaction(System.Data.IsolationLevel.Serializable))
{
    try
    {
        dbContext.Commit();
    }
    catch(DbUpdateConcurrencyException ex)
    {
        ((IObjectContextAdapter)KnowledgebaseContext).ObjectContext.Refresh(RefreshMode.StoreWins, en);
        dbContextTransaction.Rollback();
    }
}

I couldn't find much on this exception on Google or SO. Any help would be appreciated.

9
  • Where is the data you gathered from debugging? How does the model look like? How is it mapped? What is the value of its key property? Is the object attached or not? Commented Apr 20, 2015 at 17:58
  • 1
    If you are trying to add something to the database, you need to remove it before you are trying to refresh the collection. Now, I think, when you are trying to refresh the collection, there is an entity in the collection which is not yet saved in the database nor attached to the state manager Commented Apr 20, 2015 at 18:06
  • @SaagarEliasJacky that's very helpful actually. Do you know of a resource or an article I can use that explains further on this? Commented Apr 20, 2015 at 18:07
  • 1
    Might want to refer this : stackoverflow.com/questions/1746941/objectcontext-refresh Commented Apr 20, 2015 at 18:15
  • 1
    "the same entity from two separate connections" that might cause a problem because it isn't attached in the right context, yes. Though if you say that the key value is null, what is unclear about the exception? Commented Apr 20, 2015 at 18:21

1 Answer 1

2

I have been able to solve this problem by looking at this and this. The documentation on this feature is rather scarce.

So here is the scenario(we assume that there already is a TimeStamp column the value of which gets updated with each database update):

UserA reads Entity1 and starts making changes. While UserA is making her changes, userB reads Entity1, changes it and saves it to the database. Now UserA wants to save her changes but now by definition, the exact entity that she read no longer exists. The reason for this is that the existence of that entity depends on the TimeStamp column as well which is no longer the same old value. So when I was trying to refresh Entity1 as UserA knew existed, I was getting an exception and I was not able to Refresh either.

Now we'll look at two possible solutions to a concurrency problem for an existing updated entity:

  • Ignore UserA's Changes(store wins): This basically means that one will Refresh the entity from the database. In order to do this, one should overwrite the TimeStamp field for Entity1 in UserA's context with the new one now residing on the database and then try to refresh the information from the server. This way the right entity can be located and retrieved and populated in Entity1 overwriting local changes. Look here for another approach than this.
  • Overwrite changes on the database(client wins): Here, we would overwrite the TimeStamp field and then attempt the update again. By doing so, the EF would no longer detect the update as a conflict and the data on the server is overwritten. The previously referred links contain examples for this case as well.

I don't know exactly for sure why I was getting the exception when using the Refresh method. I switched to using SetValues and GetDatabaseValues and such and my problem was solved.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.