【问题标题】:How to trigger lazy loading on a navigation property?如何触发导航属性的延迟加载?
【发布时间】:2013-08-12 22:58:28
【问题描述】:

您必须“触摸”多少导航属性才能确保延迟加载集合?

我正在使用 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 对象来自我们不知道是否已检索到集合的其他地方。

【问题讨论】:

    标签: c# entity-framework lazy-loading


    【解决方案1】:

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

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

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

    【讨论】:

    • 谢谢,我知道有一些方法可以急切和显式加载。我的问题是检查 null 是否会延迟加载集合?
    【解决方案2】:

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

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

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

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

    【讨论】:

    • 因此检查 null 将加载集合和附加代码: List alist = aresource.MyResources.ToList() 不是必需的。对吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多