2013-03-08 103 views
1

我有單元測試,我在每個測試方法之前創建和接種一個SQLCE4數據庫。單元測試拋出ObjectDisposedException與Ob​​jectContext

在測試方法,如果我有這樣的查詢:

var maxGroupLevel = repository.Get<GroupLevel>().Max(g => g.Id); 

它會拋出下面的異常:

System.ObjectDisposedException: The ObjectContext instance has been disposed and can no longer be used for operations that require a connection. 
Result StackTrace: 
at System.Data.Objects.ObjectContext.EnsureConnection() 
    at System.Data.Objects.ObjectQuery`1.GetResults(Nullable`1 forMergeOption) 
    at System.Data.Objects.ObjectQuery`1.System.Collections.Generic.IEnumerable<T>.GetEnumerator() 
    at System.Linq.Enumerable.Single[TSource](IEnumerable`1 source) 
    at System.Data.Objects.ELinq.ObjectQueryProvider.<GetElementFunction>b__3[TResult](IEnumerable`1 sequence) 
    at System.Data.Objects.ELinq.ObjectQueryProvider.ExecuteSingle[TResult](IEnumerable`1 query, Expression queryRoot) 
    at System.Data.Objects.ELinq.ObjectQueryProvider.System.Linq.IQueryProvider.Execute[S](Expression expression) 
    at System.Data.Entity.Internal.Linq.DbQueryProvider.Execute[TResult](Expression expression) 
    at System.Linq.Queryable.Max[TSource,TResult](IQueryable`1 source, Expression`1 selector) 

但是,如果我把一個ToList()調用查詢它的工作原理:

var maxGroupLevel = repository.Get<GroupLevel>().ToList().Max(g => g.Id); 

怎麼回事?另外,如果我將數據庫的創建/播種移動到構造函數而不是TestInitialize方法,並在TestInitialize中創建新的上下文,那麼它一切正常。但是,我不想這樣做,因爲我希望數據庫在每次測試之前處於已知狀態。

+0

我們需要兩件事情 - 存儲庫類的代碼和測試代碼(實例化上下文和存儲庫的部分)。 – 2013-03-08 09:11:50

+0

我有[此SSCCE]的確切問題(http://pastebin.com/apRns9mV) – Eregrith 2013-10-09 11:34:30

回答

2

你的代碼的第一個版本被推遲首次maxGroupLevel查詢

var maxGroupLevel = repository.Get<GroupLevel>().Max(g => g.Id); 

代碼的第二個版本運行查詢那裏,然後在上面的代碼和第一參考之間這樣的地方,直到maxGroupLevel上下文正在處理中。如果沒有其他代碼的可見性,則比這更難以提供幫助。

0

沒有查看代碼的其餘部分,很難確定確切的問題。但是,在處理與ObjectDisposedException異常相關的實體框架時,您可能需要 瞭解兩件事情。

1)直到從數據庫中提取所有數據後才能處理數據上下文。

2)一個LINQ語句創建一個IQueryable,直到枚舉它
(例如用它在每個環)或將其轉換爲一個列表或一個陣列,其不執行。

相關問題