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

c# entity-framework extension-methods

Question

I'm new to EF and I'm trying to use an extension method which converts from my Database type User to my info class UserInfo.
I'm using database first if that makes a difference?

My code below gives the error

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

try
{
    IQueryable<User> users;
    using (var dataContext = new dataContext())
    {
        users = dataContext.Users
                  .Where(x => x.AccountID == accountId && x.IsAdmin == false);
        if(users.Any() == false)
        {
            return null;
        }
    }
    return users.Select(x => x.ToInfo()).ToList(); // this line is the problem
}
catch (Exception ex)
{
    //...
}

I can see why it would do it, but I also don't understand why the result of the where statement isn't being saved into the users object?

So I guess my main question is why doesn't it work and secondly what's the right way of using extension methods and EF?

1
34
2/19/2016 10:45:36 AM

Accepted Answer

This question & answer lead me to believe that IQueryable require an active context for its operation. That means you should try this instead:

try
{
    IQueryable<User> users;

    using (var dataContext = new dataContext())
    {
        users = dataContext.Users.Where(x => x.AccountID == accountId && x.IsAdmin == false);

        if(users.Any() == false)
        {
            return null;
        }
        else
        {
            return users.Select(x => x.ToInfo()).ToList(); // this line is the problem
        }
    }


}
catch (Exception ex)
{
    ...
}
35
5/23/2017 12:10:18 PM

Popular Answer

Objects exposed as IQueryable<T> and IEnumerable<T> don't actually "execute" until they are iterated over or otherwise accessed, such as being composed into a List<T>. When EF returns an IQueryable<T> it is essentially just composing something capable of retrieving data, it isn't actually performing the retrieve until you consume it.

You can get a feel for this by putting a breakpoint where the IQueryable is defined, vs. when the .ToList() is called. (From inside the scope of the data context as Jofry has correctly pointed out.) The work to pull the data is done during the ToList() call.

Because of that, you need to keep the IQueryable<T> within the scope of the data context.



Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow