我正在开发一个WCF数据服务 . 当我尝试从客户端访问它时,我得到以下异常:
ObjectContext实例已被释放,不能再用于需要连接的操作 .
码:
[WebGet]
public IQueryable<Student> GetUsersByClassId(string classId)
{
Check.Argument.IsNotEmptyOrNull(classId, "classId");
using (var db = new schoolContext(connectionString))
{
((IObjectContextAdapter)db).ObjectContext.ContextOptions.ProxyCreationEnabled = false;
((IObjectContextAdapter)db).ObjectContext.ContextOptions.LazyLoadingEnabled = false;
var studentQry = from s in db.Student.Include("Class")
where s.Class.Id == classId
select s;
if(studentQry == null)
return new List<Student>().AsQueryable();
else
return studentQry;
}
4 回答
我怀疑问题出在标记为
...
的代码中,您没有显示 .确保在返回之前完全评估您的查询 . 例如,而不是只做:
尝试做:
编辑:
现在你've changed your question to reflect that you'返回
IQueryable<T>
而不是IEnumerable<T>
,还有一个单独的问题 . 通过从您的方法返回IQueryable<T>
,您建议该类型可以直接在服务器端"queried" .但是,WCF正在通过网络对其进行序列化,并且需要使用具体的实现类型 . 允许
IEnumerable<T>
,但不允许IQueryable<T>
. 您应该将其切换为将完全评估的类型,以便可以正确传递结果 .这是因为Using语句 . 当您的函数完成执行时,它会处理对象上下文 . 枚举结果IQueryable时,它会尝试使用disposed,因此您将获得Exception . 删除使用,让你的服务实现IDisposable并在IDisposable.Dispose()中处理你的对象上下文
它可能是客户端试图访问子属性,例如,如果student.classes是另一个实体,并且您尝试在客户端访问它 . 需要在任何子实体上指定include
这是你的使用导致它 . 在linq查询求值之前,将放置DataContext . 您可以返回studentQry.ToList()并查看是否有效 . 如果没有,请尝试
最后,它很难看,但如果你不使用,你将不会遇到这个问题 . 它最终应该通过垃圾收集进行处理和清理 .