2015-04-26 2 views
1

У меня есть три объекта, сгенерированные Entity Framework. Один из них - event, и это свойство навигации называется frogs и user_bookings. Я опубликовал связанный с ним вопрос до того, как выполнить подзапрос, который, похоже, работает, но он мешает мне отменить ленивую загрузку свойства.Переопределить ленивую загрузку анонимного типа с помощью LINQ для объекта

var evts = from evt in context.events.Include("frogs") 
      where evt.event_id < 10 
      select evt; 

Это работает - навигационное свойство frogs загружается.

Однако, когда я изменить LINQ к этому:

var evts = from evt in context.events.Include("frogs") 
      where evt.event_id < 10 
      select new 
      { 
       Event = evt, 
       HasBooked = evt.user_bookings.Any(x => x.user_id == 1) 
      }; 

Я получаю ошибку, пытаясь не получить доступ к frogs, потому что ObjectContext больше не существует. Я попытался удалить виртуальный из определения класса для класса event, но это просто приводит к пустым спискам лягушек, когда они определенно существуют!

+0

«потому что ObjectContext больше не существует», почему бы это быть? Конечно, не из-за какого-то кода, размещенного здесь. – usr

+0

Да, я думаю, я знаю, почему появляется сообщение. Данные пытаются получить, когда я попрошу об этом для представления, которое отображает его, и к этому времени оно было удалено. Мой вопрос заключается в том, что мне нужно сделать, чтобы заставить его загружать данные во время запроса для второго варианта? Я знаю, что я могу добавить 'include' в первом примере, но это не работает для второго, поэтому я предполагаю, что он не находится в правильном месте, когда добавлена ​​часть' select new'. –

ответ

3

Это by design. Include игнорируется, когда результатом запроса является проекция , даже когда проекция содержит объект, который может содержать свойства Include d.

Я не знаю, почему EF реализовал его таким образом. Если проекция не содержит каких-либо объектов, но это всего лишь какой-то тип (анонимный или нет), нет цели Include, поэтому игнорирование имеет смысл. Но если проекция содержит цель Include (Event в вашем случае), мне кажется, что они могли решить эту работу. Но, ну, они этого не сделали.

Возможно, это связано с тем, что правила, когда Include фактически имеют эффект less obvious than you might expect. В вашем случае форма запроса изменяется после Include, поэтому его игнорируют.

Вы могли бы работать вокруг этого также запрашивая frogs:

from evt in context.events.Include("frogs") 
where evt.event_id < 10 
select new 
{ 
    Event = evt, 
    Frogs = evt.frogs, 
    HasBooked = evt.user_bookings.Any(x => x.user_id == 1) 
}; 

Теперь каждый Event также будет иметь его frogs коллекция заполнена (из-за отношений) адресной привязкой. Но есть две ошибки. В коллекции не отмечены как заряженные, так -

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

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

+0

Спасибо - это очень подробное и полезное объяснение. –

Смежные вопросы