ObjectContext实例已被释放,不能再用于需要连接的操作

时间:2011-03-29 17:49:01

标签: c# wcf entity-framework exception-handling wcf-data-services

我正在开发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 个答案:

答案 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;

最后,它很难看,但如果你不使用,你将不会遇到这个问题。它应该最终通过垃圾收集进行处理和清理。