Search code examples
c#asp.net-mvc-3objectcontext

ObjectContext access error


I am getting this error:

The ObjectContext instance has been disposed and can no 
longer be used for operations that require a connection.

I understand why I am getting the error. However, what I do not understand is why one situation will cause the error while another will not. Here are the two situations.

Case One (causes error):

        List<SomeObject> someobjects;
        using (var gm = new GenericRepository<SomeObject>())
        {
            someobjects = gm.Get().ToList();
        }
        vm.SomeObjectSelectList = slf.getSpecificList(someobjects);

What is happening here is a List<> is being filled from a database using a generic repository. After that, the list is then sent to a factory (slf) for creating select lists that are used in the view model (vm). When used in this fashion, the error above occurs. The reason is that inside of the factory there is this line of code:

w => w.Date + " " + w.Child.FirstName + " " + w.Child.LastName);

Although the list of someobjects is sent just fine, its nested objects are not, and when the call to .Child is called the db context is called and the error is caused.

Case Two (causes no error):

        List<SomeObject> someobjects;
        using (var gm = new GenericRepository<SomeObject>())
        {
            someobjects = gm.Get().ToList();
            vm.SomeObjectSelectList = slf.getSpecificList(someobjects);
        }

In this case, no error is caused. However, from the first case it is obvious that the database context is being contacted.

How does the factory have access to the context when the context is inside of the repository?


Solution

  • The factory doesn't have access to the context - it is someobjects that internally uses the context to retrieve the property values when you first access them. Since your context is disposed after the using block, trying to access the properties then will throw an exception.

    You can imagine e.g. the Child property implementation to be something like this:

    private Person _child = null;
    public Person Child
    {
        get
        {
            return _child ?? GetandSetChildFromContext();
        }
    }
    

    The value of Child is retrieved lazily from the context only when needed - if you want to eagerly include related properties use an Include() query - this is advisable i.e. if you know already that you will need certain related properties every time. This is somewhat made difficult by the fact that you use a repository layer on top of EF - make sure that repository supports Include queries.