如何触发导航属性的延迟加载

本文关键字:延迟加载 属性 导航 何触发 | 更新日期: 2023-09-27 18:27:17

您需要"触摸"多少导航属性才能确保延迟加载集合?

我使用的是开启延迟加载的EntityFramework5.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对象来自其他地方,我们不知道集合是否已检索到。

如何触发导航属性的延迟加载

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

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

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

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

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

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

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