你的位置:首页 > ASP.net教程

[ASP.net教程]关于EF中virtual ICollection 的一点问题


 
 
场景:
今天发现有一个查询很慢,根据Id对单条数据进行查询要300ms,这个完全是不正常的。然后断点进去看,发现,居然把里面所有的 virtual ICollection 的所有数据(这条数据大概有5个virtual ICollection 字段)都加载了。
问题:
之前,很多的文章都说, virtual ICollection<T> 就可以实现延迟加载,那么为什么这里会加载所有的数据出来。
查完一些资料后,我做了以下实验:
准备工作:创建一个控制台应用程序;通过Nuget安装EF6,VS2015
创建Model,UserInfo以及DepartmentInfo ,DepartmentInfo 跟UserInfo是一对多的关系。
代码如下:
DepartmentInfo
1 public class DepartmentInfo2   {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 UserInfo2   {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,
实验结果如下:

 

结论:
通过Include,实现UserInfos加载。
如果要通过添加virtual实现按需加载数据,则需要TestEFDbContext的构造函数加上 this.Configuration.LazyLoadingEnabled = false;
或者是,不加Virtual以及this.Configuration.LazyLoadingEnabled = false;
显然,不加Virtual以及this.Configuration.LazyLoadingEnabled = false;更方便。
那么,Virtual的作用是什么?为什么那么多的文章都是推荐添加Virtual