我首先使用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
。
我错过了什么吗?
答案 0 :(得分:6)
您看到的效果称为关系修正。
实际上导航属性是不是显式加载的。查询_dbContext.Programs.ToList()
仅从数据库加载整个Programs
表。这只是一个简单的SQL查询(如SELECT * FROM ProgramsTable
),没有任何WHERE
子句,也没有任何JOIN
相关的行。
当您访问program.Programs
和program.OwnerProgram
导航属性时,此处也不会发生延迟加载(如果您禁用它,并且禁用动态代理,则确实无法加载)。
当您的查询结果具体化时,将填充导航属性,因为您的查询(加载所有程序)将加载导航属性可以引用的所有程序。 EF检测到那些相关实体已经在内存中并自动将它们放入导航属性中。
如果您不加载所有程序,则可以验证这一点,但仅限于一个程序:
Program program = _dbContext.Programs.FirstOrDefault();
现在,program.Programs
和program.OwnerProgram
将为null
- 除非加载的program
是其自己的program.OwnerProgram
集合的一部分或是其自己的{{1} }}
答案 1 :(得分:2)
“EF仍会加载本程序的Programs和OwnerProgram属性 类“
这是正确的行为,但不是懒洋洋地加载导航属性,而是急切地加载它们。
这意味着在检索Program
实体并填充导航属性时,将立即执行检索导航属性值所需的数据库查询。
当LazyLoadingEnabled
设置为true
时,在您尝试访问导航属性之前,不会触发这些查询。这也适用于当您将鼠标悬停在导航属性上并附加调试器时,这可能会导致您认为实体未被延迟加载,实际上它们是 - 调试器正在访问导航属性,因此实体框架加载它。
您可以运行this one等SQL分析器,以便在调试代码时准确查看何时触发查询。
答案 2 :(得分:0)
使用上面的示例,EF仍然会加载程序和OwnerProgram Program类的属性。我试过删除虚拟 关键字,禁用代理创建并验证 模型本身上的LazyLoadingEnabled = false。
我错过了什么吗?
您需要删除初始化这些属性的默认构造函数。