2015-04-26 91 views
1

我有三個由Entity Framework生成的實體。一種是event,它包含稱爲frogsuser_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 designInclude在查詢結果是投影時被忽略,即使投影包含的實體可能包含Include d屬性。

我不知道爲什麼EF以這種方式實現它。如果投影不包含任何實體,但只是某種類型(匿名或不是),則不存在目標,因此忽略它是有意義的。但是,如果投影確實包含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

謝謝 - 這是一個非常詳細和有用的解釋。 –