Я использую самотрекинг сущностей в клиент-серверном приложении WCF. Моя служба WCF возвращает различные объекты, и они могут быть обновлены с использованием соответствующих методов обновления.
Некоторое время это работало хорошо, но сейчас у меня проблемы. Чтобы сосредоточиться, я ограничу это обсуждение конкретным случаем, упрощенным до самого необходимого.
Одна из моих таблиц называется SystemDefinition. У него нет внешних ключей, но у другой таблицы (Route) есть внешний ключ. Следовательно, он имеет единственное свойство навигации в модели объекта (называемое Маршруты). Все остальные столбцы являются скалярами. Таблица и соответствующие сущности имеют столбец первичного ключа с именем Id типа Guid. База данных SQL Server Compact v3.5.
Чтобы воспроизвести проблему, я могу:
- Извлечение одного объекта SystemDefinition с использованием метода GetSystem () моего WCF-сервиса
- В клиенте вызовите MarkAsDeleted () для объекта
- Вызовите UpdateSystem (), передав сущность в качестве параметра
Код в UpdateSystem () просто (несущественный код удален для ясности):
_objectContext.SystemDefinitions.ApplyChanges(system);
_objectContext.SaveChanges();
Сущность извлекается без условия Include (), что означает, что коллекция Routes пуста (и в любом случае ошибка все равно возникает, если в Route нет строк с внешними ключами для SystemDefinition). Таким образом, сущность SystemDefinition, которую я передаю методу Update, является единственной сущностью в графе . И все же я получаю следующее исключение:
InvalidOperationException:
AcceptChanges не может продолжаться, потому что
ключевые значения объекта конфликтуют с
другой объект в
ObjectStateManager. Убедитесь, что
ключевые значения уникальны перед вызовом
AcceptChanges.
Исключение выдается при первом вызове метода (ApplyChanges). Я уверен, что ObjectContext свежий, новый, созданный для каждого вызова метода.
Я отлаживал код до самого конца (в ObjectContext.FixupKey ()), но код не имеет для меня никакого смысла, и в исходном коде Microsoft нет комментариев, указывающих, какое условие вызывает это на самом деле означает.
Конечно, сообщение вводит в заблуждение? В обновлении участвует только одна сущность. Что может происходить?
PS. Я нашел сообщение на форуме, предлагающее, что переопределение методов GetHashCode () и Equals () для классов сущностей может помочь. Это имело бы некоторый смысл, если бы ошибка была вызвана тем, что ObjectStateManager не смог определить, что сущность для обновления фактически совпадает с какой-либо сущностью в контексте. Я попробовал это (используя частичные классы), но, к сожалению, это не помогло. Так что теперь я потерялся. Любые предложения приветствуются.