首页 文章

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

提问于
浏览
5

我正在开发一个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 回答

  • 2

    我怀疑问题出在标记为 ... 的代码中,您没有显示 .

    确保在返回之前完全评估您的查询 . 例如,而不是只做:

    return studentQry;
    

    尝试做:

    return studentQry.ToList();
    

    编辑:

    现在你've changed your question to reflect that you'返回 IQueryable<T> 而不是 IEnumerable<T> ,还有一个单独的问题 . 通过从您的方法返回 IQueryable<T> ,您建议该类型可以直接在服务器端"queried" .

    但是,WCF正在通过网络对其进行序列化,并且需要使用具体的实现类型 . 允许 IEnumerable<T> ,但不允许 IQueryable<T> . 您应该将其切换为将完全评估的类型,以便可以正确传递结果 .

  • 6

    这是因为Using语句 . 当您的函数完成执行时,它会处理对象上下文 . 枚举结果IQueryable时,它会尝试使用disposed,因此您将获得Exception . 删除使用,让你的服务实现IDisposable并在IDisposable.Dispose()中处理你的对象上下文

  • 2

    它可能是客户端试图访问子属性,例如,如果student.classes是另一个实体,并且您尝试在客户端访问它 . 需要在任何子实体上指定include

  • 15

    这是你的使用导致它 . 在linq查询求值之前,将放置DataContext . 您可以返回studentQry.ToList()并查看是否有效 . 如果没有,请尝试

    List<Student> retValue;
    retValue = studentQry.ToList();
    return retValue;
    

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

相关问题