簡體   English   中英

為什么我需要ToList()來避免處置上下文錯誤?

[英]Why do I need a ToList() to avoid disposed context errors?

我正在編寫一些代碼來使用EntityFrameWork訪問數據庫。 代碼是:

public IEnumerable<Rows> GetRows(int id)
{
    using (var context = new ApplicationDbContext())
    {
        var repository = new EntityFrameWorkRepository<int, RowEntity>(context);
        //need a ToList() here to prevent disposed dbcontext errors
        return repository.GetRowsFromDb(id).ToList();
    }
}

GetRowsFromDb()使用LINQ查詢數據庫並使用id過濾結果。

我最初在沒有ToList()調用的情況下編寫了上面的方法,但是當我嘗試訪問返回的IEnumerable中的對象時,我會得到一個關於dbcontext已被處置的異常。 我不明白上面的代碼如何解決問題,雖然它確實有效。 我假設ToList()深度復制對象,這可能提供了與上下文/數據庫的必要分離,但是原始對象肯定可以使用嗎?

您需要調用ToListToArray或枚舉EF返回的數據的其他方法的原因是LINQ中的查詢執行被延遲 :在您明確地獲取數據之前,不會處理數據。 當您的方法返回已獲取查詢數據的上下文時(您的using塊會快速處理這種情況),導致您看到的異常。

這樣做是為了使代碼不花時間處理您不需要的數據。 例如,您可以編寫開始讀取客戶端數據的代碼,並在中間停止。 如果查詢執行沒有延遲,那么你將花費時間和內存來獲取查詢的“尾部”,只是將其拋棄。 延遲執行使您可以控制:您可以根據自己的需要決定要保留哪些數據,或者根據您計划對數據執行的操作將整個集合存儲到內存中。

如果不調用.ToList() ,則 using子句完成后將對可枚舉進行求值,因此在評估查詢之前將處理數據上下文。

IMO,您應該考慮讓您的存儲庫處理這個(通過調用.ToList() ),否則此問題代表泄漏的實現細節。

如果沒有ToList() ,則只返回枚舉數而不是實際的對象集合。 嘗試訪問集合時將獲取實際對象。 但在這種情況下,您需要的是上下文和存儲庫,因為您從數據庫訪問它們。 但由於它已經超出了using子句的范圍,因此兩者都被處理掉了例外。

我假設ToList()是深度復制對象

不完全 - 在你調用ToList之前,你所擁有的只是一個查詢 在您枚舉它或通過ToListToArray etc將其轉換為具體集合之前,您不會得到結果

當然原始對象應該可用嗎?

沒有 - 它被處理掉了,這是告訴系統對象已完成其工作而不再需要的方式。 您仍有未執行查詢的事實不會將上下文保持在可用狀態。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM