場(chǎng)景:
今天發(fā)現(xiàn)有一個(gè)查詢很慢,根據(jù)Id對(duì)單條數(shù)據(jù)進(jìn)行查詢要300ms,這個(gè)完全是不正常的。然后斷點(diǎn)進(jìn)去看,發(fā)現(xiàn),居然把里面所有的 virtual ICollection 的所有數(shù)據(jù)(這條數(shù)據(jù)大概有5個(gè)virtual ICollection 字段)都加載了。
問(wèn)題:
之前,很多的文章都說(shuō), virtual ICollection<T> 就可以實(shí)現(xiàn)延遲加載,那么為什么這里會(huì)加載所有的數(shù)據(jù)出來(lái)。
查完一些資料后,我做了以下實(shí)驗(yàn):
準(zhǔn)備工作:創(chuàng)建一個(gè)控制臺(tái)應(yīng)用程序;通過(guò)Nuget安裝EF6,VS2015
創(chuàng)建Model,UserInfo以及DepartmentInfo ,DepartmentInfo 跟UserInfo是一對(duì)多的關(guān)系。
代碼如下:
DepartmentInfo
復(fù)制代碼
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 }
復(fù)制代碼
UserInfo
復(fù)制代碼
1 public class UserInfo 2  { 3  [Key] 4 public int Id { get; set; } 5 6 public string Name { get; set; } 7 }
復(fù)制代碼
TestEFDbContext
復(fù)制代碼
  public TestEFDbContext() : base("TestConn")
        {
            
        } public DbSet<UserInfo> UserInfos { get; set; } public DbSet<DepartmentInfo> DepartmentInfos { get; set; }
復(fù)制代碼
 
實(shí)驗(yàn)1:
DbContext、DepartmentInfo代碼不變,DepartmentInfo的UserInfos前面不加virtual。
實(shí)驗(yàn)結(jié)果如下:
結(jié)論:在Department的UserInfos前面不加virtual的情況下,UserInfos沒(méi)有被加載。
 
實(shí)驗(yàn)2:
DbContext、DepartmentInfo代碼不變,DepartmentInfo的UserInfos前面不加virtual。
在查詢語(yǔ)句添加上Include
實(shí)驗(yàn)結(jié)果如下:
結(jié)論:通過(guò)Include,實(shí)現(xiàn)UserInfos加載。
 
實(shí)驗(yàn)3:

修改DepartmentInfo代碼

在DepartmentInfo中的UserInfos添加virtual關(guān)鍵字,
修改后的代碼如下
 
實(shí)驗(yàn)結(jié)果如下:
結(jié)論,在加上添加了Virtual之后,UserInfos直接被加載進(jìn)來(lái)了。
 
實(shí)驗(yàn)4:
修改DepartmentInfo代碼
在DepartmentInfo中的UserInfos添加virtual關(guān)鍵字,如實(shí)驗(yàn)3,
然后在TestEFDbContext的構(gòu)造函數(shù)加上 this.Configuration.LazyLoadingEnabled = false;
實(shí)驗(yàn)結(jié)果如下:
結(jié)論,在加上添加了Virtual之后TestEFDbContext的構(gòu)造函數(shù)加上 this.Configuration.LazyLoadingEnabled = false,UserInfos沒(méi)有被加載。
 
實(shí)驗(yàn)5:
修改DepartmentInfo代碼
在DepartmentInfo中的UserInfos添加virtual關(guān)鍵字,如實(shí)驗(yàn)3,
然后在TestEFDbContext的構(gòu)造函數(shù)加上 this.Configuration.LazyLoadingEnabled = false;(如實(shí)驗(yàn)4)
最后在查詢語(yǔ)句添加上Include,
實(shí)驗(yàn)結(jié)果如下: