如何触发导航属性的延迟加载
本文关键字:延迟加载 属性 导航 何触发 | 更新日期: 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中检索一个实体,而不是导航属性集合中的所有实体。