2012-08-08 69 views
1

我有一個名爲MyItems的實體表,並且此表中的每個項目都有一個到另一個表的外鍵。我想簡單地通過我的項目環和訪問字符串每個項目的外鍵對象的「名稱」屬性,像這樣:在實體循環時實體框架異常(使用ToList()時工作)雖然)

foreach (var myItem in (from q in context.MyItems select q)) 
{ 
    string testName = myItem.ForeignItem.Name 
} 

當我這樣做,ForeignItem是空的,我得到一個InvalidOperationException時我試圖訪問ForeignItem:

已經有一個打開的DataReader與此命令相關聯,其中 必須先關閉。

然而 - 如果我不是調用ToList()像這樣:

(from q in context.MyItems select q).ToList() 

我的外鍵對象來填充就好了。我意識到ToList()將會很昂貴,因爲整個表將立即被檢索。我懷疑在延遲加載的背後有什麼問題,但我正在理解,它應該應該的工作,而不要求ToList()

我忽略了什麼嗎?

編輯:我在想也許使用var是造成問題的,所以我嘗試使用

foreach (MyItem myItem in (from q in context.MyItems select q)) 
{ 
    // loop contents 
} 

代替 - 相同的結果。 myItem的屬性填充,但外鍵對象保持爲空。

編輯#2:我只在整個應用程序中使用一個對象上下文和一個Linq-to-Entities語句,所以我無法解釋其他DataReader在何處運行。我還應該注意到,這個錯誤發生在循環中的第一個對象,所以它不是被檢索的前一個項目的結果。

+0

是ForeignItem.Name需要加載的東西嗎? – Brian 2012-08-08 18:40:29

+0

你試過把myItem.ForeignItem.Load();實際嘗試獲取ForeignItem.Name值之前? – Thousand 2012-08-08 18:43:10

+0

@Brian它應該加載,期間。爲什麼它在我調用'ToList()'的時候起作用,但當我不調的時候不是最大的問題。 – 2012-08-08 18:43:26

回答

5

你寫了myItem而不是q。你應該使用這個:

(from q in context.MyItems select q) 

或者更簡單地說,你可以這樣寫:

context.MyItems 

關於你更新的問題,這似乎是因爲你之前先啓動一個新的查詢已經完成執行。可能的解決方案:

  • 當您運行原始查詢時包含子項目。

    foreach (var myItem in context.MyItems.Include("ForeignItem")) { ... } 
    
  • 啓用MultipleActiveResultSets。

相關

+0

我正在爲我的對象名稱進行消毒處理,錯字與問題無關。我已經更新了問題中的代碼。 – 2012-08-08 18:31:34

+0

是否還存在延遲執行問題? IIRC,LINQ查詢推遲執行,直到他們通過類似於ToList/ToArray的方式執行。 ForEach是否會執行? – 2012-08-08 18:32:01

+1

@ kevinmajor1是的,'foreach'會強制執行。 – Servy 2012-08-08 18:37:02

0

這裏就是我終於實現了,按照馬克的建議,使用Include()

(from q in context.MyItems.Include("ForeignItemOne").Include("ForeignItemTwo").Include("ForeignItemThree") select q) 

順便說一句,設置MultipleActiveResultSets爲真也有效。現在,我將使用Include(),因爲應用程序很小,並且只有一條Linq語句。