C# 如何在导航属性上触发延迟加载?
您需要“触摸”导航属性多少才能确保集合的延迟加载 我正在使用EntityFramework5.0,启用了延迟加载。考虑一个简单的类:C# 如何在导航属性上触发延迟加载?,c#,entity-framework,lazy-loading,C#,Entity Framework,Lazy Loading,您需要“触摸”导航属性多少才能确保集合的延迟加载 我正在使用EntityFramework5.0,启用了延迟加载。考虑一个简单的类: public class MyResource { string name {get;set;} public virtual ICollection<ResourceEvent> ResourceEvents{ get; set; } } 公共类MyResource { 字符串名称{get;set;} 公共虚拟ICollection
public class MyResource
{
string name {get;set;}
public virtual ICollection<ResourceEvent> ResourceEvents{ get; set; }
}
公共类MyResource
{
字符串名称{get;set;}
公共虚拟ICollection 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
}
}
}
使用(context=newmydbcontext)
{
MyResource aresource=context.MyResources.Where(a=>a.Name==myname.Single();
//现在我想延迟加载ResourceEvents集合
if(aresource.MyResources!=null)//此集合是否加载?
{
List alist=aresource.MyResources.ToList();//或者我必须添加这个吗?
foreach(列表中的ResourceEvent re)//(或在arSource.MyResources中)
{
//做点什么
}
}
}
我知道我可以使用Include(),但假设MyResource对象来自其他地方,我们不知道是否已检索到集合。您可以通过以下方式加载集合:
context.Entry(aresource).Collection(p => p.MyResources).Load();
对于单个引用,请使用
Reference()
而不是Collection()
您可以通过以下方式加载集合:
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中检索一个实体,而不是导航属性集合中的所有实体。访问导航属性将枚举集合,这意味着EF将在此时加载所有实体,而不是逐个加载。这一点很重要,因为如果您想要第一个实体,并且编写了
areasource.MyResources.first()
,EF将加载该集合的所有实体对象,即使您只计划使用一个aresource.MyResources
将枚举集合,然后执行First()
操作
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
}
}
}
为了避免这种情况,您需要获取该导航属性的IQueryable并在此基础上进行构建。对于我提到的示例,您将执行以下操作:
context.Entry(aresource).Collection( c => p.MyResources ).Query().First()
此语句将仅从DB中检索一个实体,而不是导航属性集合中的所有实体。谢谢,我知道有很多方法可以快速、显式地加载。我的问题是检查null是否会延迟加载集合?谢谢,我知道有很多方法可以快速和显式地加载。我的问题是检查null是否会延迟加载集合?因此,检查null将加载集合,并且不需要额外的代码:List alist=aresource.MyResources.ToList()。正确吗?因此检查null将加载集合,并且不需要额外的代码:List alist=aresource.MyResources.ToList()。对的
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
}
}
}