Entity Framework - 即使使用ToList()也能实现延迟加载

9

首先,我正在使用EF 6.0的Code First方法。

我的配置设置为启用"代理创建"和"延迟加载"。

我的问题是: 延迟加载是否适用于返回IEnumerable(而不是IQueryable)的方法结果?

我认为下面的代码更加说明:

public void Test()
{
    var company = GetCompanies().FirstOrDefault();

    if (company.Employees.Count() > 0)
    {
        //I got here without errors!
    }
}

public IEnumerable<Company> GetCompanies() 
{
    var company = context.Companies.ToList();
    //Note that I did not Include the Employee (child table)

    return company;              
}

请注意我说的这句话:“我没有错误地到达这里!”。 这意味着即使在调用ToList()之后,延迟加载仍在起作用。 我曾认为将IQueryable转换为ListIEnumerable后,EF将失去进行延迟加载的能力。
我已经注意到代理仍然对由GetCompanies方法返回的实体启用(在调试模式下,我可以看到类似于System.Data.Entity.DynamicProxies.Company_7035BEA374959AC1的丑陋哈希值...)。
即使在不同的DLL上调用它时,延迟加载也可以正常工作。 这是正确的吗? 我的意思是,即使我的方法返回一个IEnumerable(而不是IQueryable),不同的DLL是否可以在我的数据库中进行后续调用?
非常感谢任何澄清。
1个回答

5
请注意我所说的评论:“我没有错误地到达这里!” 这意味着即使在ToList()调用之后,惰性加载仍在工作。
这就是惰性加载的全部意义:您可以在需要时(即当您访问属性时)从数据库获取实体,而不仅仅是在第一次执行查询时(即您对.ToList()的调用)。
懒惰加载甚至在调用不同DLL时也能正常工作。这是正确的吗?我的意思是,即使我的方法返回IEnumerable(而不是IQueriable),不同的DLL是否可以在我的数据库中进行后续调用?
是的,这是正确的,但要小心,如果您处置上下文,惰性加载将无法工作(它会抛出ObjectDisposedException)。此外,尽管您的代码将正常工作,但由于生成的SQL请求数量可能会导致性能问题。
顺便说一句:个人建议不要使用惰性加载。请参见https://stackoverflow.com/a/21379510/870604

1
当我在某个查询上调用.ToList()时,这并不意味着它会变成急切加载而不是延迟加载吗? - Nashmár

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接