我有单元测试,我在每个测试方法之前创建和播种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中创建新的上下文,那么一切正常。但是,我不想这样做,因为我希望在每次测试之前数据库处于已知状态。
答案 0 :(得分:2)
您的第一个代码版本将延迟到第一次查询maxGroupLevel
var maxGroupLevel = repository.Get<GroupLevel>().Max(g => g.Id);
代码的第二个版本在那里运行查询,然后在上面的代码和对maxGroupLevel
的第一个引用之间的某处处理上下文。如果没有其他代码的可见性,那么它的帮助就更难了。
答案 1 :(得分:0)
如果不查看其余代码,很难确定确切的问题。但你可能想要 在使用与ObjectDisposedException异常相关的Entity Framework时要了解两件事。
1)在从数据库中提取所有数据之前,不得处理数据上下文。
2)linq语句创建一个IQueryable,直到你枚举它才会执行 (例如,在每个循环中使用它)或将其转换为列表或数组。