I have been following this article, <a href="http://blogs.msdn.com/b/adonet/archive/2011/01/31/using-dbcontext-in-ef-feature-ctp5-part-6-loading-related-entities.aspx" rel="nofollow">http://blogs.msdn.com/b/adonet/archive/2011/01/31/using-dbcontext-in-ef-feature-ctp5-part-6-loading-related-entities.aspx</a>
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.Answer1:
If the relationship between
Student is a <strong>many-to-many</strong> relationship the behaviour you are seeing is expected (although confusing, I'd admit). First of all, if you read what Intellisense says about the
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 <strong>will be loaded into the associated System.Data.Entity.DbContext, System.Data.Objects.ObjectContext or other cache on the client</strong>. This is equivalent to calling ToList and then throwing away the list without the overhead of actually creating the list.</blockquote>
...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 <strong>one-to-many</strong> relationship is populated when you call
Load is not really the result of this method but of a subsequent processing of the context called <strong>relationship span or fix-up</strong>, a processing that does not take place for many-to-many relationships.
In this question and answer are more details: <a href="https://stackoverflow.com/questions/6141988/ef-4-1-loading-filtered-child-collections-not-working-for-many-to-many" rel="nofollow">EF 4.1 loading filtered child collections not working for many-to-many</a>
The quintessence is that - for a many-to-many relationship - you must populate the navigation collection directly by using
ToList() instead of
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 <em>and</em> populate the navigation collection in
class1 at the same time.