Странное исключение InvalidOperationException при обновлении объекта с помощью RIA Services

Я работаю с EF4.1, RIA Services и Silverlight. У меня несколько странная проблема в сценарии обновления.

Модель предметной области довольно проста; он имеет дело с запросами и лицами. У них отношение 1 к n. Таким образом, Гражданин может иметь несколько Запросов, хотя на самом деле этого никогда не произойдет, поскольку приложение просто не предоставляет для этого функциональности.

Запрос имеет свойство "Срочно", которое я изменяю на true и затем пытаюсь сохранить. Все идет хорошо, пока не начнется фактическое сохранение с помощью этого метода:

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

который в значительной степени является стандартным методом, сгенерированным RIA Services (за исключением обработчика try/catch, который я добавил для целей отладки). Затем я получаю следующую ошибку:

Когда я проверяю ChangeSet, я не вижу никаких запросов для добавления, поэтому я уверен, что добавил его не случайно.

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

я не понимаю этого... В ObjectStateManager буквально нет добавленных объектов, в ChangeSet нет добавленных объектов; откуда, черт возьми, это идет? Я отслеживал, какие свойства изменяются, поэтому я уверен, что ключ не перезаписывается, не добавляется или еще какая-то приблуда.

Может ли кто-нибудь пролить свет здесь? Сводит меня с ума уже несколько дней...


person rumblefx0    schedule 19.02.2013    source источник
comment
Я не думаю, что дело в том, что вы добавляете его где-то еще. Есть ли код, который мог бы загрузить объект до выполнения этого метода обновления? Другой запрос, выполняемый в том же цикле?   -  person Anthony Pegram    schedule 19.02.2013
comment
Что вы видите в окне CallStack? Разве вы не можете отследить постоянный вызов операции?   -  person Davut Gürbüz    schedule 20.02.2013
comment
Как упомянул Энтони Пеграм, вы не можете прикрепить модель после загрузки объекта с тем же ключом. Изменения должны быть применены к прикрепленному объекту.   -  person Ouarzy    schedule 20.02.2013
comment
Вот что я сделал, я загрузил объект с данным ключом, изменил 1 свойство и попытался сохранить. Метод UpdateRequest создается службой RIA, поэтому он должен работать...   -  person rumblefx0    schedule 20.02.2013


Ответы (1)


Мне удалось исправить это, используя следующую логику, в основном мы проверяем, прикреплена ли уже сущность. Если это так, мы не прикрепляем его повторно, а просто обновляем значения. В противном случае мы прикрепляем его.

        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);
        }
person rumblefx0    schedule 25.07.2016