2009-10-28 92 views
1

我有這種方法,這將從WCF客戶端調用,但對於我的測試,我使用本地「添加項目引用」。我收到錯誤消息,說明它在處理後無法調用DataContext。LINQ TO SQL我在這裏丟失了一些明顯的東西嗎?

public IEnumerable<Server> GetServers() 
    { 
     // initialze to null 
     ServersDataContext sdc = null; 

     try 
     { 
      // get connected 
      using (sdc = GetDataContext()) 
      { 
       // disable this deferred loading 
       sdc.DeferredLoadingEnabled = false; 

       var relations = from svr in sdc.Servers; // complex linq here 

       // return 
       return relations; 
      } 
     } 
     catch (Exception ex) 
     { 
      LogError(ex, "fwizs.Internal"); 
      throw; 
     } 
     finally 
     { 
      if (sdc != null) 
      { 
       sdc.Dispose(); 
      } 
     } 
    } 

這裏是我如何使用方法,它給出了這樣的錯誤:「無法訪問已釋放的對象」

if (da.GetServers() 
     .Select(sv => sv.ServerID == s.ServerID).Count() == 0) 
    { 

     // do work since we found it 
    } 

使用這個返回的IEnumerable對象。選擇()方法改掉跑回數據庫做出選擇。序列化爲WCF後,我不認爲這會是一個問題,但我希望我的本地測試工作。

回答

4

在方法內實現查詢以確保數據庫調用在處理數據上下文之前實際執行。

var relations = from svr in sdc.Servers; 

return relations.ToList(); 
0

你已經處置您的datacontext與使用 所以你不能處理它另一次在最後

+1

雖然它沒有很好的理由處置兩次,但不會導致錯誤。任何正確實現IDisposable的對象都可以被處置多次而不會造成傷害。 – Guffa

2

以這種方式使用時,「使用」關鍵字是保證處置一旦其出的語法糖範圍 - 發生在「返還關係」之後。

+0

即使在例外的情況下? – Nate

+0

@Nate:是的,這是「使用」的全部要點。否則,只寫x.Dispose()會更容易。 – erikkallen

3

LINQ是懶惰的,所以查詢只在這裏定義,沒有迭代低谷。

因此,會發生什麼是您定義查詢,然後關閉datacontext。不久之後,您嘗試迭代低谷,這意味着您嘗試通過之前已關閉的SQL連接進行查詢。

從MSDN:

This method is implemented using deferred execution. The immediate return value is an object that stores all the information required to perform the action. The query represented by this method is not executed until the object is enumerated either by calling its GetEnumerator method directly or by using foreach in Visual C# or For Each in Visual Basic.

4

的DeferredLoadingEnabled屬性控制關係如何加載,主數據不是如何加載。

您可以簡單地使用ToList方法,以確保數據被加載到內存中:

return relations.ToList(); 
+0

他似乎對DeferredLoadingEnabled沒有做到他認爲應該做的事情特別困惑,所以我懷疑這個答案在這個特殊情況下是最有用的。 +1。 –

0

除了別人說什麼的都有關於使用.ToList,這也應該工作,並與懶惰的執行:

public IEnumerable<Server> GetServers() { 
    // initialze to null 
    ServersDataContext sdc = null; 
    try { 
     // get connected 
     using (sdc = GetDataContext()) { 
      // disable this deferred loading 
      sdc.DeferredLoadingEnabled = false; 
      foreach (var relation in from svr in sdc.Servers) // complex linq here 
       yield return relations; 
     } 
    } 
    catch (Exception ex) { 
     LogError(ex, "fwizs.Internal"); 
     throw; 
    } 
    finally { 
     if (sdc != null) { 
      sdc.Dispose(); 
     } 
    } 
} 
相關問題