0

Example Code:

private static list;
public void SetList ()
{
var query = Container.Advices.Where ();
list= query.ToList();
}

public void doStuff ()
{
var temp= list.where (...).ToList ();
}

problem situation:

When i call the first time SetList, all worked fine. Now, a second is SetList called. I can see in the method, there are all objects, but in the second method doStuff is an exception thrown: ObjectContext is disposed ... I'm not understanding why. I saw the data is loaded correctly in the list and not a second later i can ' t load the navigation properties.

How can i fix this?

EDIT

What i do: 1. I call SetList() to initialize the list First time 2. doStuff all worked fine 3. I recreate the list with SetList 4. Next call to doStuff ended in exception on the try to use navigation properties:

var temp = list.where ( m=> m.Address.id==addressId).ToList ()

Failed on the second time with exception: ObjectContext is disposed. ..

maerlyn
  • 83
  • 9
  • Maybe this could help you solve your problem? http://stackoverflow.com/questions/18398356/how-to-solve-the-error-the-objectcontext-instance-has-been-disposed-and-can-no-l – HDD Jun 09 '15 at 14:46
  • 2
    You're not showing where the context is disposed, so it's impossible to tell exactly. Don't use a shared member (`Container`) for contexts. They're cheap - create them, do what you need to do, and dispose of them (making sure to hydrate any objects with `ToList` or something similar before disposing it). – D Stanley Jun 09 '15 at 14:46
  • I edited my question...maybe its better to understand. I have to use the Container. :/ – maerlyn Jun 09 '15 at 14:57
  • Are you eagerly fetching Address as shown in HDD's link? Add .Include(m => m.Address) in SetList. Are both steps happening in the same controller action? You get that error when the context is disposed as in the end of a controller action. – Steve Greene Jun 09 '15 at 15:20
  • I learned from my boss, navigation properties like address load automatically, but i give your idea a try. No, the second method is called by viewmodel. – maerlyn Jun 09 '15 at 15:41
  • if you don't use `.include()` for a navigation property before you call `.ToList()`, that navigation property won't be included in the list to be used as a predicate later. – Claies Jun 09 '15 at 16:13
  • Think of it this way; almost everything in the database is connected to something else through navigation properties. If entity framework were to fetch everything connected to your object, you may as well be fetching the entire database for every item loaded. as soon as you call `ToList()`, you are "finalizing" your selection from the database, and can't go back later to fetch other tables of data. `.Include()` let's you ensure that data is in the list. – Claies Jun 09 '15 at 16:17

1 Answers1

1

The problem is likely that by default Navigation Properties are lazy-loaded. This means that they're not actually returned by the database until you attempt to access them. The ObjectContext that you are using to create list is being disposed somewhere, and that's a good thing because you do not what the lifetime of your context to be too long.

The reason that your next call errors on list.where(m => m.Address.id == addressId).ToList() is because you are going to iterate over the list and access the Address property. Since this is not loaded yet, EF will attempt to query the database using the parent ObjectContext of the entities in list. Since the parent context is disposed, this is not possible.

The better and likely more performant way to accomplish this would be to eagerly load the Address property when you load list.

Change your original query to look like the following:

list = queryContainer.Advices
    .Where(m => /* Some Predicate */)
    .Include(m => m.Address).ToList();
mclark1129
  • 7,532
  • 5
  • 48
  • 84