您需要多少“触摸”导航属性以确保延迟加载集合?
我正在使用启用延迟加载的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对象来自其他我们不知道是否已检索到集合的地方。
答案 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()
此语句仅从数据库中检索一个实体,而不从导航属性集合中检索所有实体。