1

我有单元测试,我在每个测试方法之前创建和播种 SQLCE4 数据库。

在测试方法中,如果我有这样的查询:

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 中创建新上下文,那么一切正常。但是,我不想这样做,因为我希望在每次测试之前数据库处于已知状态。

4

2 回答 2

2

您的代码的第一个版本被推迟到第一次查询 maxGroupLevel

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

代码的第二个版本在那里运行查询,然后在上述代码和对maxGroupLevel上下文的第一个引用之间的某个地方被处理。如果没有其他代码的可见性,则比这更难提供帮助。

于 2013-03-08T09:08:24.377 回答
0

如果不查看其余代码,就很难确定确切的问题。但是在使用与 ObjectDisposedException 异常相关的实体框架时,您可能想知道两件事。

1) 在从数据库中获取所有数据之前,不得释放数据上下文。

2) 一个 linq 语句创建一个 IQueryable,直到您对其进行枚举
(例如,在 for 每个循环中使用它)或将其转换为列表或数组时才会执行该 IQueryable。

于 2015-01-10T15:26:17.070 回答