Search code examples
c#.netsilverlightentity-frameworkwcf-ria-services

Strange InvalidOperationException when updating entity with RIA Services


I'm working with EF4.1, RIA Services and Silverlight. I'm having a somewhat bizarre problem in an update scenario.

The domain model is quite simple; it deals with Requests and Persons. They have a 1-to-n relationship. So a Citizen can have multiple Requests although in reality this will never occur since the app simply does not provide functionality to do so.

Request has a property called 'Urgent', which I change to true and then try to save. All goes well until the actual persisting begins via this method:

    public void UpdateRequest(Request currentRequest)
    {
        Request original = ChangeSet.GetOriginal(currentRequest);
        try
        {
            ObjectContext.Requests.AttachAsModified(currentRequest, original);
        }
        catch (Exception ex)
        {
            // weirdness here!
        }
    }

which is pretty much the standard generated method by RIA Services (except the try/catch handler which I added for debugging purposes.) I then get the following error:

When I check the ChangeSet, there are no Requests to be added, so I'm sure I didn't add it by accident.

An object with the same key already exists in the ObjectStateManager. The ObjectStateManager cannot track multiple objects with the same key.

i don't understand this... There are literally no added objects in the ObjectStateManager, the ChangeSet has no added objects; where the hell is this coming from? I tracked which properties are being changed, so I'm sure the key is not overwritten, nor is it being added or some other funkyness.

Can anyone shed some light here? Driving me crazy for several days so far...


Solution

  • I managed to fix it using the following logic, basically we're checking if the entity is attached already. If it is, we don't re-attach it but just update the values. Otherwise, we attach it.

            ObjectStateEntry entry;
            // Track whether we need to perform an attach
            bool attach;
            if (ObjectContext.ObjectStateManager.TryGetObjectStateEntry(ObjectContext.CreateEntityKey("Requests", currentRequest), out entry))
            {
                // Re-attach if necessary
                attach = entry.State == EntityState.Detached;
            }
            else
            {
                // Attach for the first time
                attach = true;
            }
            if (attach)
            {
                ObjectContext.DocumentRequests.AttachAsModified(currentRequest, original);
            }
            else
            {
                ObjectContext.Requests.ApplyCurrentValues(currentRequest);
            }