【转】EntityFramework(EF)贪婪加载和延迟加载的选择和使用

时间:2023-01-24 10:10:26

原谅:http://www.weixq.cn/Article/Detail/906

贪婪加载:顾名思议就是把所有要加载的东西一 次性读取

 using (var context = new MyDbContext())
{
var orders = from o in context.Orders.Include("OrderDetails") select o;
}

当读取订单信息orders的时候,我们希望把订单的详细信息也读取出来,那么这里我们使用Include关键字将关联表也加载进 来。

延迟加载:即当我们需要用到的时候才进行加载(读取)

当我们希望浏览某条订单信息的时候,才显示其对应的订单详细记录时,我们希望使用延迟加载来实现,这样不仅加快的了 读取的效率,同时也避免加载不需要的数据。延迟加载通常用于foreach循环读取数据时。

那么我们在定义Model的时候,需要在属性前面添加virtual关键字。如下

 public class Order
{
public int OrderID { get; set; }
public string OrderTitle { get; set; }
public string CustomerName { get; set; }
public DateTime TransactionDate { get; set; }
public virtual List<OrderDetail> OrderDetails { get; set; }
}

如果我们想要禁止使用延迟加载,那么最好的方法是在DbContext类的构造方法中声明

 public class MyDbContext:DbContext
{
public MyDbContext()
{
this.Configuration.LazyLoadingEnabled = false;
}
}

总结:

贪婪加载:
1、减少数据访问的延迟,在一次数据库的访问中返回所有的数据。
2、一次性读取所有相关的数据,可能导致部分数据实际无需用到,从而导致读取数据的速度变慢,效率变低

延迟加载:
1、只在需要读取关联数据的时候才进行加载
2、可能因为数据访问的延迟而降低性能,因为循环中,每一条数据都会访问一次数据库,导致数据库的压力加大

综上所述,我们应该比较清楚时候应该使用哪种机制?我个人的建议是:

1、如果是在foreach循环中加载数据,那么使用延迟加载会比较好, 因为不需要一次性将所有数据读取出来,这样虽然有可能会造成n次数据库的查询,但 是基本上在可以接受的范围内。

2、如果在开发时就可以预见需要一次性加载所有的数据,包含关联表的所有数据, 那么使用使用贪婪加载是比较好的选择,但是此种方式会导致效率问题,特别是数据量大的情况下。