如何在导航属性上触发延迟加载?

时间:2013-08-12 14:34:59

标签: c# entity-framework lazy-loading

您需要多少“触摸”导航属性以确保延迟加载集合?

我正在使用启用延迟加载的Entity Framework 5.0。考虑一个简单的类:

public class MyResource
{
    string name {get;set;}
    public virtual ICollection<ResourceEvent> ResourceEvents{ get; set; }
}

当我在集合上设置“foreach”时,我想避免单独检索集合中的每个对象。

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
        }
    }
}

我知道我可以使用Include(),但假设MyResource对象来自其他我们不知道是否已检索到集合的地方。

2 个答案:

答案 0 :(得分:1)

您可以这样加载集合:

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

对于单引用,请使用Reference()代替Collection()

答案 1 :(得分:0)

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

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

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

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