5

我正在開發WCF數據服務。當我嘗試從客戶端訪問它,我得到這個異常:ObjectContext實例已被處置,並且不能再用於需要連接的操作

的ObjectContext的實例已經設置,不能再用於需要連接的操作。

代碼:

[WebGet] 
public IQueryable<Student> GetUsersByClassId(string classId) 
{ 
    Check.Argument.IsNotEmptyOrNull(classId, "classId"); 

    using (var db = new schoolContext(connectionString)) 
    { 
     ((IObjectContextAdapter)db).ObjectContext.ContextOptions.ProxyCreationEnabled = false; 
     ((IObjectContextAdapter)db).ObjectContext.ContextOptions.LazyLoadingEnabled = false; 

     var studentQry = from s in db.Student.Include("Class") 
         where s.Class.Id == classId 
         select s; 

     if(studentQry == null) 
      return new List<Student>().AsQueryable(); 
     else 
      return studentQry; 
} 
+1

您必須在返回它之前評估IQueryable,將它變成IEnumerable或類似的,基本上返回一個懶集合,然後在任何人有機會通過它獲取數據之前,先取出數據庫連接。 – 2011-03-29 18:11:02

回答

15

我懷疑問題是代碼標記...,這你不顯示。

確保在返回之前完全評估您的查詢。例如,而不是僅僅做:

return studentQry; 

嘗試這樣做:

return studentQry.ToList(); 

編輯:

現在,你已經改變了你的問題,以反映你返回IQueryable<T>而不是IEnumerable<T>,有一個單獨的問題。通過從您的方法返回IQueryable<T>,您建議可以在服務器端直接「查詢」類型。

但是,WCF正在通過線連接它,並且需要使用具體的實現類型。允許使用IEnumerable<T>,但不允許使用IQueryable<T>。您應該將其切換爲完全評估的類型,以便可以正確傳遞結果。

+2

感謝您的建議。我必須將返回類型更改爲IEnumerable,然後返回studentQry.ToList()而不是studentQry.AsEnumerable()或studentQry。 – Attilah 2011-03-29 18:08:20

+0

非常感謝。你爲我節省了很多頭痛。 – Attilah 2011-03-29 18:08:59

+0

@Attilah:很高興幫助;)我很高興你有這個機會。 – 2011-03-29 18:09:33

2

它可能是客戶端試圖訪問一個子屬性,例如,如果student.classes是另一個實體,並且您嘗試在客戶端訪問它。需要指定包含在任何子實體上

2

這是您使用的原因。 DataContext在linq查詢評估之前被放置。您可以返回studentQry.ToList()並查看是否有效。如果還是不行,請嘗試

List<Student> retValue; 
retValue = studentQry.ToList(); 
return retValue; 

最後,它是醜陋的,但如果你沒有一個使用使用,你不會有這個問題。它最終應該被垃圾收集處理和清理。

6

這是因爲使用語句。當你的函數完成執行時,它會處理對象上下文。當枚舉結果IQueryable時,它會嘗試使用已處理的對象,以便獲得Exception。刪除使用,讓您的服務實現IDisposable並將您的對象上下文置於IDisposable.Dispose()

+0

這是我的問題。在服務完成之前,using語句正在處理我的對象上下文。我刪除了使用聲明,這工作。 – Flea 2012-06-12 18:42:13

相關問題