user2675238
user2675238

Reputation: 21

How to trigger lazy loading on a navigation property?

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

Answers (2)

Moho
Moho

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

user2674389
user2674389

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

Related Questions