M.Armoun
M.Armoun

Reputation: 1165

Entity framework - one to many - select from both table

In my DB I have "Place" and "Image" table. "Image" has a foreign key from Place which means each place can have multiple images.

I select places like this:

var query = (from x in DB.Places
  where x.CityId == CityId 
  select x).ToList();

and when I want to access to its images by: query.Images.toList(); i get this error :

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


how should be my select query in order to get a place and it's images just by one select query ??

thanks in advance
MA.

Upvotes: 3

Views: 13064

Answers (4)

Bassam Alugili
Bassam Alugili

Reputation: 17023

First point!

You query accept only strings by Include, that means you have an abstraction on EF and I think in your case you are using DynamicLibrary.

http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx

Second Point!

The entities are not automatically loaded by accessing them, that means you are using only Eager loading and not lazy loading! --> I'm not sure what you have!

In your case you have always to include the collections, before executing any query, otherwise you will always get an empty collection!

Fix

// Include First
DbContext.Places.Include("Images"); // ---> you can go here recursively deeper for example "Images.Data"

// Then execute the query!

Third Point!

You have posted DbContext disposed exception, that means you are accessing the DbContext outside the using scope!

Fix

Do not dispose the DbContext as long as you are using it!

Upvotes: 1

Pavvy
Pavvy

Reputation: 348

If you have enabled lazy loading then you will automatically get the images of selected places. So In your case,

var query = (from x in DB.Places
where x.CityId == CityId 
select x).ToList();

as your are taking list of the objects. You will have to select particular item before accessing it's inner details.

 : query.FirstOrDefault().Images.ToList(); // only to get the images of the first record in the list. If that list has values.

If you have eager loading enabled, then you will have to use .Include() function to load the tables you want before doing first tolist. I will suggest you to go with option 1.

Upvotes: 0

Sergey Berezovskiy
Sergey Berezovskiy

Reputation: 236278

You can use eager loading:

var query = (from x in DB.Places
             where x.CityId == CityId 
             select x).Include(p => p.Images).ToList();

Method syntax looks better in that case

var query = DB.Places.Where(p => p.CityId == CityId).Include(p => p.Images).ToList();

Another option - do not dispose DbContext until you get images. E.g. if you are using using statement, just remove it or get images while you are inside using block. But it will use second database query for loading images.

Further reading: Eager Loading and Lazy Loading

Upvotes: 5

madoxdev
madoxdev

Reputation: 3890

There are 2 options:

1) Enable eager load (not good idea)

2) Keep Lazy loading and Include entity you want to get.

Option 2:

var query = DB.Places.Include(z => z.Images).Where(x => x.CityId == CityId).ToList();

The exception you are getting is because of LazyLoading enabled on context object. You are trying to access the property outside EF i guess, when it's already disposed.

In Lazy Loading call to the property for the first time is actually connecting DB and retrieving data you need.

For more information please follow that link: https://msdn.microsoft.com/en-us/library/jj574232(v=vs.113).aspx

Upvotes: 1

Related Questions