简体   繁体   中英

EF6 The operation cannot be completed because the DbContext has been disposed

I know there are a bunch of these error messages in SO because I've read them all, sadly to no avail.

I have a WebApi controller that is getting a set of 'Persons' via EF6 from a SQL Server DB. Very simple example

Things I've tried so far, with no success: - Disabling proxy generation - Disabling lazy loading - Adding Includes to get child refs with both linq and string parameters. - Replacing the using with try/finally -> dispose of DbContext. - Remove "application/xml" from supported media types via WebApiConfig - Ensured circular dependencies are attributed with [IgnoreDataMember] - ... More I cannot remember :)

Here is the PersonController Get method:

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)
        {
            ...
        }            
    }

Now no exception is thrown at ANY point in the controller. The exception is however displayed in the browser:

"<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()

The error tells me that something else is trying to read the context after the using clause has popped but I'm at a loss to know what that could be? As you can see I copy the enumerated data from the context into the local list before returning that. Got me stuffed!

Any suggestions appreciated.

The line

persons = entities.Persons.Take(5);

is a definition of how to retrieve data, but the data itself is not yet retrieved at that point ('delayed execution'). The line is located inside the using(){} construct, so right after that the DbContext is disposed. A while later the View needs the data, the DbContext is consulted, but it is closed already.

Solution:
Retrieve all data before closing the DbContext. This is frequently done using ToArray() or ToList() , whichever suits you best.

So the line should be eg:

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

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

You are actually closing the connection before fetching the data.

If this doesn't work, try remove using clause for dbcontext just to check whats happening.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM