LazyLoadingEnabled设置似乎在EF 5中不起作用

时间:2013-05-03 10:49:26

标签: entity-framework entity-framework-5

我首先使用EF模型和POCO实体以及自定义DbContexts。我的问题是设置LazyLoadingEnabled=false不会影响任何东西,导航属性仍然​​被加载。 下面是我简化的例子。

实体计划。程序可以是其他程序的一部分:

namespace Domain.Entities
{
    using System;
    using System.Collections.Generic;

    public partial class Program
    {
        public Program()
        {
            this.Programs = new HashSet<Program>();
        }

        public int Id { get; set; }
        public string Title { get; set; }
        public string Description { get; set; }
        public System.DateTime StartDate { get; set; }
        public System.DateTime EndDate { get; set; }
        public Nullable<int> ProgramId { get; set; }

        public virtual ICollection<Program> Programs { get; set; }
        public virtual Program OwnerProgram { get; set; }
    }
}

DbContext:

namespace Infrastructure.Model
{
    public class ProgramContext : DbContext
    {
        public ProgramContext()
            : base("name=MyContainer")
        {
            Configuration.LazyLoadingEnabled = false;
        }

        public DbSet<Program> Programs { get; set; }
    }
}

以下是我如何使用它:

private ProgramContext _dbContext = new ProgramContext();

// GET api/program
public IEnumerable<Program> GetPrograms()
{
    List<Program> list = _dbContext.Programs.ToList();
    return list;
}

使用上面的示例,EF仍然会加载Program类的Programs和OwnerProgram属性。我尝试删除虚拟关键字,禁用代理创建,并验证了模型本身的LazyLoadingEnabled=false

我错过了什么吗?

3 个答案:

答案 0 :(得分:6)

您看到的效果称为关系修正

实际上导航属性是不是显式加载的。查询_dbContext.Programs.ToList()仅从数据库加载整个Programs表。这只是一个简单的SQL查询(如SELECT * FROM ProgramsTable),没有任何WHERE子句,也没有任何JOIN相关的行。

当您访问program.Programsprogram.OwnerProgram导航属性时,此处也不会发生延迟加载(如果您禁用它,并且禁用动态代理,则确实无法加载)。

当您的查询结果具体化时,将填充导航属性,因为您的查询(加载所有程序)将加载导航属性可以引用的所有程序。 EF检测到那些相关实体已经在内存中并自动将它们放入导航属性中。

如果您不加载所有程序,则可以验证这一点,但仅限于一个程序:

Program program  = _dbContext.Programs.FirstOrDefault();

现在,program.Programsprogram.OwnerProgram将为null - 除非加载的program是其自己的program.OwnerProgram集合的一部分或是其自己的{{1} }}

答案 1 :(得分:2)

  

“EF仍会加载本程序的Programs和OwnerProgram属性   类“

这是正确的行为,但不是懒洋洋地加载导航属性,而是急切地加载它们。

这意味着在检索Program实体并填充导航属性时,将立即执行检索导航属性值所需的数据库查询。

LazyLoadingEnabled设置为true时,在您尝试访问导航属性之前,不会触发这些查询。这也适用于当您将鼠标悬停在导航属性上并附加调试器时,这可能会导致您认为实体未被延迟加载,实际上它们是 - 调试器正在访问导航属性,因此实体框架加载它。

您可以运行this one等SQL分析器,以便在调试代码时准确查看何时触发查询。

答案 2 :(得分:0)

  

使用上面的示例,EF仍然会加载程序和OwnerProgram   Program类的属性。我试过删除虚拟   关键字,禁用代理创建并验证   模型本身上的LazyLoadingEnabled = false。

     

我错过了什么吗?

您需要删除初始化这些属性的默认构造函数。