I'm using Entity Framework 4 with MVC and need to ensure any referenced entities I want to use in my view have been loaded before the controller method returns, otherwise the view spits out the dreaded:
The ObjectContext instance has been disposed and can no longer be used for operations that require a connection.
When selecting straight from the context, I can just use the Include(string)
method to force them to be included in the generated SQL query:
var sellers = context.Sellers.Include("Recommendations.User").ToList();
However, if I have (for example) a helper method that accepts an entity and needs all items to be loaded, there's no Include
method available.
void Test(Seller seller)
{
// ensure all recommendations and their users are loaded
}
The brute force approach is to loop through them:
foreach (var recommendation in seller.Recommendations)
recommendation.User.ToString(); // just force a load
If I have 100 recommendations, this will create 101 SQL queries behind-the-scenes. Ideally I want a method/approach that loads all Recommendation
AND User
objects with only a single trip to SQL.
Show me the money.
EDIT I'm not really interested in discussing whether this is a good or bad architecture. I've simplified my scenario for the sake of the question. Can you do what I'm asking with the EF API?
EDIT 2
Ladislav's edit offered hope of a new approach, but it seems I'm not quite there.
I can achieve what I want via this:
context.Sellers.Include("Recommendations.User").Single(s => s.Id == seller.Id);
This approach doesn't work using LoadProperty
...
context.LoadProperty(seller, "Recommendations.User");
...as it fails with the error...
The specified navigation property Recommendations.User could not be found.
Neither of these approaches work if you don't have a reference to the context.
This is an old question, but in EF6 you can accomplish loading dependent objects on an entity like this:
context.Entry(seller).Collection(s => s.Recommendations).Query().Include(r => r.User)).Load();
That would load all Recommendations
and their related Users
for the given seller
I think this is a job for your repository which should in your case expose methods like GetFullSeller (all properties loaded by Include) and GetSeller (only base entity).
Edit:
There are several ways how to load navigation properties in EF v4.
There is no automatic loading.
I'm in the same situation. I think that with EF is very easy to fall in a 101 query problem.
A solution can be to create a partial class of your Seller class (generated by EF) and implement a GetSubclassNameQ that return a IQueryable, and a GetSubclassNameQFull that return a IQueryable with eager loading.
public partial class Seller{
public IQueryable<Recommendation> GetRecommendationsQ(EntityContainer entitycontainer) {
return entitycontainer.Recommendations;
}
public IQueryable<Recommendation> GetRecommendationsQFull(EntityContainer entitycontainer) {
return this.GetRecommendationsQ(entitycontainer).Include("Recommendations.User");
}
public IQueryable<Recommendation> GetRecommendationsQ() {
return GetRecommendationsQ(new EntityContainer());
}
public IQueryable<Recommendation> GetRecommendationsQFull() {
return this.GetRecommendationsQ().Include("Recommendations.User");
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With