Entity Framework 的Lazy Loading
最近在使用EntityFramework的时候,就在想当DBContetext.ModelName的时候,是否会去数据库做一次真正的查询呢?
代码如下:
public ActionResult TestLazyLoding() { using (CompanyEntities dbContext = new CompanyEntities()) { IEnumerable<News> list = dbContext.News;//访问News集合,不产生数据库查询 int splitVar = 1;//检测点1:用来区分代码运行边界的。 foreach (News m in list) { //检测点2:迭代list,产生数据库查询,也就是LazyLoading } foreach (News m in list) { //检测点3:再次迭代list还会再次查询吗? } foreach (News m in list) { //检测点4 if (m.NewsClass != null) { //检测点5:迭代过程中,访问News的Navigate属性NewsClass看看啥情况? splitVar = 5; } } } return new EmptyResult(); }
用sqlProfiler来监控一下:
监测点1:不产生查询

断点二: 迭代集合产生LazyLoading,产生一次查询

断点三: 再次迭代依然会LazyLoading,再次产生一次查询

断点4:再次迭代集合,还是会LazyLoading

断点5:访问集合中元素的属性

断点6:完全结束后

得到结论:
1.直接通过DBContext访问数据集是不产生查询的。但是需要注意的是,如果调用了ToList(),会发生LazyLoading;
2.LasyLoading发生在对集合进行迭代时及对元素的子属性访问的时。官方给定的EasyLoading的发生的描述如下:
Lazy loading is the process whereby an entity or collection of
entities is automatically loaded from the database the first time that a
property referring to the entity/entities is accessed.
大概意思就是LazyLoading发生在当我们访问第一次访问实体或者集合的属性时。
3.如果Navigate属性是非集合,那么不一定每次访问都会产生查询。举个例子,新闻的总类别有5个,5个大类中有1000条新闻。那么在迭代新闻(News)并访问新闻的新闻类别属性(NewsClass)时,只会产生5次查询Navigate(NewsClass)属性。
4.LazyLoading确实省心,不注意使用会产生大量的查询,严重影响性能。