Entity framework 使用ObjectContext引发ObjectDisposedException的单元测试
我有一些单元测试,在每个测试方法之前,我都要创建并植入SQLCE4数据库 在测试方法中,如果我有如下查询:Entity framework 使用ObjectContext引发ObjectDisposedException的单元测试,entity-framework,objectdisposedexception,Entity Framework,Objectdisposedexception,我有一些单元测试,在每个测试方法之前,我都要创建并植入SQLCE4数据库 在测试方法中,如果我有如下查询: var maxGroupLevel = repository.Get<GroupLevel>().Max(g => g.Id); var maxGroupLevel=repository.Get().Max(g=>g.Id); 它将抛出以下异常: System.ObjectDisposedException: The ObjectContext instance ha
var maxGroupLevel = repository.Get<GroupLevel>().Max(g => g.Id);
var maxGroupLevel=repository.Get().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)
System.ObjectDisposedException:ObjectContext实例已被释放,不能再用于需要连接的操作。
结果跟踪:
在System.Data.Objects.ObjectContext.EnsureReconnection()中
位于System.Data.Objects.ObjectQuery`1.GetResults(可为null`1 forMergeOption)
位于System.Data.Objects.ObjectQuery`1.System.Collections.Generic.IEnumerable.GetEnumerator()
at System.Linq.Enumerable.Single[TSource](IEnumerable`1 source)
在System.Data.Objects.Elink.ObjectQueryProvider.b__3[TResult](IEnumerable`1序列)
在System.Data.Objects.Elink.ObjectQueryProvider.ExecuteSingle[TResult](IEnumerable`1查询,表达式queryRoot)
位于System.Data.Objects.Elink.ObjectQueryProvider.System.Linq.IQueryProvider.Execute[S](表达式)
在System.Data.Entity.Internal.Linq.DbQueryProvider.Execute[TResult](表达式)处
at System.Linq.Queryable.Max[TSource,TResult](IQueryable`1 source,表达式`1选择器)
但是,如果我在查询中放入ToList()调用,它就会工作:
var maxGroupLevel = repository.Get<GroupLevel>().ToList().Max(g => g.Id);
var maxGroupLevel=repository.Get().ToList().Max(g=>g.Id);
发生什么事了
另外,如果我将数据库的创建/种子设定移到构造函数而不是TestInitialize方法,并在TestInitialize中创建一个新上下文,那么一切都正常。但是,我不想这样做,因为我希望在每次测试之前数据库处于已知状态。您的第一个版本的代码将推迟到第一次查询maxGroupLevel时
var maxGroupLevel = repository.Get<GroupLevel>().Max(g => g.Id);
var maxGroupLevel=repository.Get().Max(g=>g.Id);
代码的第二个版本在那里运行查询,因此在上述代码和对
maxGroupLevel
的第一个引用之间的某个地方,上下文正在被释放。如果没有代码其余部分的可见性,那么就很难提供帮助 如果不研究代码的其余部分,就很难确定确切的问题。但你可能想要
在使用与ObjectDisposedException异常相关的实体框架时,需要了解两件事
1) 在从数据库中提取所有数据之前,不得释放数据上下文
2) linq语句创建IQueryable,在对其进行枚举之前不会执行该语句(例如,在for-each循环中使用它)或将其转换为列表或数组。我们需要两件事-存储库类的代码和测试的代码(实例化上下文和存储库的部分)。我对