Matthew
Matthew

Reputation: 1168

Entity Framework - Trouble with .Load()

I have been following this article, http://blogs.msdn.com/b/adonet/archive/2011/01/31/using-dbcontext-in-ef-feature-ctp5-part-6-loading-related-entities.aspx

Specifically the section titled "Applying filters when explicitly loading related entities".

I need to do something like:

db.Configuration.LazyLoadingEnabled = false;
var class = db.Classes.Find(1);
db.Entry(class).Collection(c => c.Students).Query().Where(s => s.grade > 2.0).Load();

When I step through this and watch SQL profiler I see the query that loads the class. Then I see the query that should load the Students, but class.Students is never populated and remains null. However if I copy the students query from SQL profiler and run in myself, the appropriate students are returned. It seems that Entity Framework is running the students query and getting to proper results back, but is not attaching them to the class object.

There are ways I can work around this, but I wondering if I missed a step, or if I am not using .Load() properly.

Upvotes: 3

Views: 324

Answers (1)

Slauma
Slauma

Reputation: 177133

If the relationship between Class and Student is a many-to-many relationship the behaviour you are seeing is expected (although confusing, I'd admit). First of all, if you read what Intellisense says about the Load method...

Enumerates the query such that for server queries such as those of System.Data.Entity.DbSet, System.Data.Objects.ObjectSet, System.Data.Objects.ObjectQuery, and others the results of the query will be loaded into the associated System.Data.Entity.DbContext, System.Data.Objects.ObjectContext or other cache on the client. This is equivalent to calling ToList and then throwing away the list without the overhead of actually creating the list.

...it doesn't say that the navigation collection of the entity you run the query with gets populated, only that the result is loaded into the context.

That the navigation collection in case of a one-to-many relationship is populated when you call Load is not really the result of this method but of a subsequent processing of the context called relationship span or fix-up, a processing that does not take place for many-to-many relationships.

In this question and answer are more details: EF 4.1 loading filtered child collections not working for many-to-many

The quintessence is that - for a many-to-many relationship - you must populate the navigation collection directly by using ToList() instead of Load():

var class1 = db.Classes.Find(1);
class1.Students = db.Entry(class1).Collection(c => c.Students).Query()
    .Where(s => s.grade > 2.0).ToList();

This will load the students into the context and populate the navigation collection in class1 at the same time.

Upvotes: 2

Related Questions