我正在开发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;
}
答案 0 :(得分:15)
我怀疑问题出现在标有...
的代码中,但您没有显示。
确保在返回之前完全评估您的查询。例如,而不仅仅是:
return studentQry;
尝试做:
return studentQry.ToList();
编辑:
既然您已经更改了问题以反映您正在返回IQueryable<T>
而不是IEnumerable<T>
,则会有一个单独的问题。通过从您的方法返回IQueryable<T>
,您建议可以直接在服务器端“查询”该类型。
但是,WCF正在通过网络对其进行序列化,并且需要使用具体的实现类型。允许IEnumerable<T>
,但不允许IQueryable<T>
。您应该将其切换为完全评估的类型,以便正确传递结果。
答案 1 :(得分:6)
这是因为Using语句。当您的函数完成执行时,它会处理对象上下文。枚举结果IQueryable时,它会尝试使用disposed,因此您将获得Exception。删除使用,让你的服务实现IDisposable并在IDisposable.Dispose()
中处理你的对象上下文答案 2 :(得分:2)
客户端可能正在尝试访问子属性,例如,如果student.classes是另一个实体,并且您尝试在客户端访问它。需要在任何子实体上指定包含
答案 3 :(得分:2)
这是你的使用导致它。在linq查询求值之前,将放置DataContext。您可以返回studentQry.ToList()并查看是否有效。如果没有,请尝试
List<Student> retValue;
retValue = studentQry.ToList();
return retValue;
最后,它很难看,但如果你不使用,你将不会遇到这个问题。它应该最终通过垃圾收集进行处理和清理。