Сущность и наследование: NotSupportedException

Я получаю

System.NotSupportedException: все объектов в EntitySet "Entities.Message" должен иметь уникальную первичные ключи. Однако, экземпляр тип "Model.Message" и экземпляр типа "Model.Comment" оба имеют то же значение первичного ключа

но я понятия не имею, что это значит.

Используя EF4, у меня есть куча сущностей типа Message. Некоторые из этих сообщений на самом деле являются подтипом, комментариями, наследованием по таблице за тип. Просто

 DB.Message.First();

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

Изменить: Я разработал (должен был раньше), что проблема заключается в ошибке хранимой процедуры, получающей мои сообщения. Способ, которым в настоящее время настроен так, что все поля, относящиеся к сообщению, выбираются, таблица комментариев игнорируется sproc. Затем контекст переходит к обману, возможно, выбирая те сообщения, которые также являются комментариями, как вы предложили. Как правильно это сделать, это центральная проблема. Я нашел некоторые указания для решения в http://social.msdn.microsoft.com/Forums/en-US/adodotnetentityframework/thread/bb0bb421-ba8e-4b35-b7a7-950901adb602.

Ответ 1

Как вы видите, похоже, что Context получает комментарий как сообщение (не зная, что это комментарий). Позже вы запрашиваете фактический комментарий, поэтому контекст извлекает комментарий. Теперь у вас есть два экземпляра объекта в Контексте с тем же идентификатором - один - это сообщение, а одно - комментарий.

Кажется, что исключение не выбрасывается до тех пор, пока оба объекта не будут загружены (т.е. когда вы попытаетесь получить доступ к сообщению во второй раз). Если вы можете найти способ удалить сообщение из контекста при загрузке комментария, это может решить вашу проблему.

Другим вариантом может быть использование модели "Таблица для иерархии". Это приводит к плохой конструкции базы данных, но в конце дня вы должны использовать то, что работает.

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

Также рассмотрите возможность использования Композиции над наследованием, чтобы сообщение содержало 0..1 CommentDetails.

Последнее предложение - удалить зависимость от Entity Framework от вашего кода управления и создать слой доступа к данным, который ссылается на EF и извлекает ваши объекты. DAL может превращать объекты Entity Framework в другой набор объектов Entity, которые легче использовать в коде. Такой подход приведет к большому количеству служебных данных кода, но может быть подходящим, если вы не можете использовать Entity Framework для создания модели Entity, которая представляет ваши объекты так, как вы хотите работать с ними.

Подводя итог, если MS не исправляет эту проблему, нет решения вашей проблемы, которая не предполагает переосмысления вашего подхода. К сожалению, платформа Entity Framework не идеальна, особенно для сложных моделей Entity - вам может быть лучше создать свой собственный DAL и вообще обходить EF.

Ответ 2

Похоже, вы перетаскиваете две записи в память одну в сообщение и одну в комментарий.

Возможные ошибки:

  • Есть два физических сообщения с одним и тем же идентификатором
  • То же сообщение выводится как сообщение и комментарий
  • Одно и то же сообщение дважды вытягивается в один и тот же контекст

Проблема иногда исчезает при перезапуске, указывает на проблему с очисткой контекста. Вы используете "использование" операторов.

Есть ли у вас функциональность для перехода от сообщения к комментарию?

Ответ 3

Я не парень типа EF (занятый работой с NHibernate, еще не успел обновиться с EF), поэтому я могу быть абсолютно неправым, но может быть проблема в том, что две таблицы (с тех пор вы используете наследование по таблице за тип) имеют первичные ключи, которые сталкиваются?

Если вы проверяете данные в обеих таблицах, выполняются ли значения первичных ключей?