Entity Framework: Работа с отсоединенными и прикрепленными объектами - PullRequest
4 голосов
/ 23 декабря 2008

Во-первых, позвольте мне изложить, что я хотел бы сделать. Предположим, у меня есть три типа EntityObject, MetaData, Data1 и Data2. MetaData, как и следовало ожидать, имеет ссылку на один экземпляр, каждый из Data1 и Data2. Теперь для каждого MetaData я могу вычислить value.

Пока все просто. Теперь я бы хотел, чтобы пользователь поиграл с различными комбинациями Data1 и Data2 и посмотрел, какие value они могут получить. Это, очевидно, требует создания экземпляров MetaData. Теперь, если я не хочу кластеризовать базу данных со всеми этими записями MetaData, то я хотел бы создать объекты сущности в контексте в памяти без вызова SaveChanges(), чтобы записать его обратно в БД , Однако это создает проблему в том, что всякий раз, когда я пытаюсь получить доступ к ссылкам Data1 и Data2 в памяти MetaData, я получаю следующее исключение:

InvalidOperationException не обрабатывается

Исходный запрос для этого EntityCollection или EntityReference не может быть возвращен, когда связанный объект находится либо в добавленном состоянии, либо в отключенном состоянии и не был первоначально получен с помощью параметра объединения NoTracking.

Если я сделаю так, как предложено, и "передам" объект в БД, я столкнусь с проблемой беспорядка.

Как бы то ни было, код ошибки выглядит примерно так:

MetaData temp = MetaData.CreateMetaData(0);

MetaData.Data1 = <existing Data1 from context>;
MetaData.Data2 = <existing Data2 from context>;

//Exception here
if (!MetaData.Data1Reference.isLoaded)
    MetaData.Data1Reference.Load();

Кажется, у этого парня была похожая проблема.

1 Ответ

11 голосов
/ 23 декабря 2008

IsLoaded относится только к свойствам экземпляров, которые были материализованы из базы данных. Как вы обнаружили, он не возвращает полезную информацию для экземпляров, которые не были материализованы из базы данных.

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

if ((temp.EntityState != System.Data.EntityState.Added) && 
    (!temp.Data1Reference.IsLoaded)) temp.Data1Reference.Load();

Я здесь приукрашиваю некоторые тонкости. Для начала EntityState объявлен с FlagsAttribute, поэтому он может содержать Добавлено, не будучи равно добавлен. Кроме того, ничего из этого не требуется, если Data1Reference не равен NULL, так что вы можете просто проверить это в первую очередь. Дело в том, что вы можете написать код, соответствующий вашей ситуации, но он должен учитывать полное состояние temp, а не только его свойства.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...