EF6由于已经处理了DbContext,因此无法完成操作

时间:2016-04-25 12:17:53

标签: c# sql-server entity-framework asp.net-web-api

我知道SO中有一堆这些错误消息,因为我已经全部阅读过这些消息,但遗憾的是无济于事。

我有一个WebApi控制器,它通过EF6从SQL Server数据库获取一组“人员”。非常简单的例子

到目前为止我尝试过的事情没有成功:   - 禁用代理生成   - 禁用延迟加载   - 添加Includes以获取带有linq和字符串参数的子引用。   - 用try / finally替换使用 - >处理DbContext。   - 通过WebApiConfig从支持的媒体类型中删除“application / xml”   - 确保循环依赖性归因于[IgnoreDataMember]   - ...更多我不记得了:))

这是 PersonController 获取方法:

public IEnumerable<Person> Get()
    {
        try
        {            
            IEnumerable<Person> persons = null;
            using (PersonContext entities = new PersonContext())
            {
                entities.Configuration.ProxyCreationEnabled = false;
                entities.Configuration.LazyLoadingEnabled = false;
                persons = entities.Persons.Take(5);
            }
            return persons;
        }
        catch(Exception ex)
        {
            ...
        }            
    }

现在控制器中的任何一点都不会抛出异常。但是,例外情况显示在浏览器中:

"<Error><Message>An error has occurred.<\Message>
<ExceptionMessage>The 'ObjectContent`1' type failed to serialize the response body for content type 'application\/json; charset=utf-8'.
<\ExceptionMessage> 
<ExceptionType>System.InvalidOperationException<\ExceptionType>
<StackTrace/>
<InnerException>
    <Message>An error has occurred.<\/Message>
    <ExceptionMessage>**The operation cannot be completed because the DbContext has been disposed.**<\/ExceptionMessage>
    <ExceptionType>System.InvalidOperationException<\/ExceptionType>
    <StackTrace>   at 
        System.Data.Entity.Internal.LazyInternalContext.InitializeContext()

错误告诉我其他东西试图在使用子句弹出后读取上下文但是我不知道那可能是什么?如您所见,我在返回之前将枚举数据从上下文复制到本地列表中。让我塞满了!

任何建议表示赞赏。

2 个答案:

答案 0 :(得分:4)

该行

persons = entities.Persons.Take(5);

是如何检索数据的定义,但此时尚未检索到数据本身(&#39;延迟执行&#39;)。该行位于using(){}构造内部,因此在此之后处置DbContext。稍后View需要数据,请咨询DbContext,但它已经关闭。

解决方案:
在关闭DbContext之前检索所有数据。这通常使用ToArray()ToList()来完成,最适合您。

所以该行应该是例如:

persons = entities.Persons.Take(5).ToArray();

答案 1 :(得分:1)

persons = entities.Persons.Take(5).ToList()ToArray

在获取数据之前,您实际上是在关闭连接。

如果这不起作用,请尝试删除using的{​​{1}}子句,以检查发生了什么。