1

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.

4

2 回答 2

1

您可以通过以下方式加载集合:

context.Entry(aresource).Collection(p => p.MyResources).Load();

对于单个引用,请使用Reference()而不是Collection().

于 2013-08-12T14:50:27.660 回答
0

访问导航属性将枚举集合,这意味着 EF 将在那时加载所有实体 - 而不是一一加载。了解这一点很重要,因为假设您想要第一个实体并且您编写areasource.MyResources.First()EF 将加载该集合的所有实体对象,即使您只打算使用一个。aresource.MyResources将枚举集合,然后First()执行操作。

为避免这种情况,您需要获取该导航属性的 IQueryable 并以此为基础。对于我提到的示例,您将执行以下操作:

context.Entry(aresource).Collection( c => p.MyResources ).Query().First()

此语句将仅从数据库中检索一个实体,而不是导航属性集合中的所有实体。

于 2013-08-12T14:58:28.623 回答