Reputation: 21
How much do you have to "touch" a navigation property to assure lazy loading of a collection?
I am using Entity Framework 5.0 with lazy loading turned on. Consider a simple class:
public class MyResource
{
string name {get;set;}
public virtual ICollection<ResourceEvent> ResourceEvents{ get; set; }
}
When I set up a "foreach" on the collection, I want to avoid individual retrieval of each object in the collection.
using(context = new MyDBContext)
{
MyResource aresource = context.MyResources.Where(a=>a.Name==myname).Single();
//now I want to lazy load the ResourceEvents collection
if(aresource.MyResources!=null) // will this load collection?
{
List<ResourceEvent> alist = aresource.MyResources.ToList();//or must I add this?
foreach(ResourceEvent re in alist)// (or in aresource.MyResources)
{
//do something
}
}
}
I know I can use Include(), but assume the MyResource object comes from somewhere else where we don't know whether collection has been retrieved or not.
Upvotes: 1
Views: 1193
Reputation: 16498
Accessing the navigation property will enumerate the collection which means EF will load all the entities at that time - not one by one. This is important to know because if, let's say, you want the first entity, and you write areasource.MyResources.First()
, EF will load all entity objects for that collection even though you're only planning on using one. aresource.MyResources
will enumerate the collection AND THEN the First()
operation will be performed.
To avoid that, you want to get the IQueryable for that navigation property and build on that. For the example I mentioned, you would do the following:
context.Entry(aresource).Collection( c => p.MyResources ).Query().First()
This statement will only retrieve the one entity from the DB and not all the entities in the navigation property collection.
Upvotes: 0
Reputation: 1143
You can load collections this way:
context.Entry(aresource).Collection(p => p.MyResources).Load();
For single references use Reference()
instead of Collection()
.
Upvotes: 1