场景:
今天发现有一个查询很慢,根据Id对单条数据进行查询要300ms,这个完全是不正常的。然后断点进去看,发现,居然把里面所有的 virtual ICollection 的所有数据(这条数据大概有5个virtual ICollection 字段)都加载了。
问题:
之前,很多的文章都说, virtual ICollection<T> 就可以实现延迟加载,那么为什么这里会加载所有的数据出来。
查完一些资料后,我做了以下实验:
准备工作:创建一个控制台应用程序;通过Nuget安装EF6,VS2015
创建Model,UserInfo以及DepartmentInfo ,DepartmentInfo 跟UserInfo是一对多的关系。
代码如下:
DepartmentInfo
复制代码
1 public class DepartmentInfo 2  { 3  [Key] 4 public int Id { get; set; } 5 6 public string Name { get; set; } 7 8 public ICollection<UserInfo> UserInfos { get; set; } 9 }
复制代码
UserInfo
复制代码
1 public class UserInfo 2  { 3  [Key] 4 public int Id { get; set; } 5 6 public string Name { get; set; } 7 }
复制代码
TestEFDbContext
复制代码
  public TestEFDbContext() : base("TestConn")
        {
            
        } public DbSet<UserInfo> UserInfos { get; set; } public DbSet<DepartmentInfo> DepartmentInfos { get; set; }
复制代码
 
实验1:
DbContext、DepartmentInfo代码不变,DepartmentInfo的UserInfos前面不加virtual。
实验结果如下:
结论:在Department的UserInfos前面不加virtual的情况下,UserInfos没有被加载。
 
实验2:
DbContext、DepartmentInfo代码不变,DepartmentInfo的UserInfos前面不加virtual。
在查询语句添加上Include
实验结果如下:
结论:通过Include,实现UserInfos加载。
 
实验3:

修改DepartmentInfo代码

在DepartmentInfo中的UserInfos添加virtual关键字,
修改后的代码如下
 
实验结果如下:
结论,在加上添加了Virtual之后,UserInfos直接被加载进来了。
 
实验4:
修改DepartmentInfo代码
在DepartmentInfo中的UserInfos添加virtual关键字,如实验3,
然后在TestEFDbContext的构造函数加上 this.Configuration.LazyLoadingEnabled = false;
实验结果如下:
结论,在加上添加了Virtual之后TestEFDbContext的构造函数加上 this.Configuration.LazyLoadingEnabled = false,UserInfos没有被加载。
 
实验5:
修改DepartmentInfo代码
在DepartmentInfo中的UserInfos添加virtual关键字,如实验3,
然后在TestEFDbContext的构造函数加上 this.Configuration.LazyLoadingEnabled = false;(如实验4)
最后在查询语句添加上Include,
实验结果如下: