延迟加载vs即时加载

本文关键字:加载 vs 延迟加载 | 更新日期: 2023-09-27 18:02:21

在什么情况下迫切加载比延迟加载更有利?

实体框架中的延迟加载是加载和访问相关实体时的默认现象。然而,急切加载是指对所有这些关系进行强制加载的实践。

我问这个问题,因为很明显,延迟加载更加资源友好,即使我们使用ToList()方法,我们仍然可以利用延迟加载行为。

然而,我认为可能延迟加载增加了对实际数据库的请求数量,也许这就是为什么有时开发人员使用Inlcude方法强制加载所有关系的原因。

例如,当在MVC 5中使用Visual Studio自动脚手架时,在控制器中自动创建的Index方法总是使用Eager Loading,我一直有一个问题,为什么微软在这种情况下使用默认的Eager Loading。

如果有人向我解释一下在什么情况下急切加载会比延迟加载更有益,为什么我们要使用它,而有一些更资源友好的东西作为延迟加载?

延迟加载vs即时加载

我认为这样分类关系比较好

何时使用即时加载

  1. 在一对多关系的"一方"中,您确定与主实体在任何地方都使用。就像文章的用户属性一样。产品的类别属性。
  2. 一般来说,当关系不是太多和急切加载将是一个很好的做法,以减少服务器上的进一步查询。

何时使用延迟加载

  1. 几乎在一对多关系的每个"集合端"。如用户物品或某一类别的产品
  2. 你知道你不会马上需要一个属性。

注意:就像Transcendent说的那样,可能存在延迟加载的处理问题。

立即加载:急切加载帮助您一次加载所有需要的实体。即相关对象(子对象)用它的父对象自动加载。

何时使用

  1. 在关系不太大的情况下使用急切加载。因此,主动加载是减少服务器上进一步查询的好方法。
  2. 当你确定你将在任何地方使用与主实体相关的实体时,使用急切加载。

延迟加载:在惰性加载的情况下,相关对象(子对象)不会自动加载直到它们被请求为止。默认情况下LINQ支持延迟加载。

何时使用

  1. 当你使用一对多集合时,使用延迟加载。
  2. 当你确定你没有立即使用相关实体时使用延迟加载。

注意:实体框架支持三种方式加载相关数据-主动加载、延迟加载和显式加载。

延迟加载将产生多个SQL调用,而急于加载可能会通过一个"更重"的调用(连接/子查询)来加载数据。

例如,如果你的web和sql服务器之间有一个高ping,你会用Eager loading而不是lazy loading 1-by-1加载相关项目。

考虑以下情况

public class Person{
    public String Name{get; set;}
    public String Email {get; set;}
    public virtual Employer employer {get; set;}
}
public List<EF.Person> GetPerson(){
    using(EF.DbEntities db = new EF.DbEntities()){
       return db.Person.ToList();
    }
}

现在这个方法被调用后,你不能再延迟加载Employer实体了。为什么?因为db对象被处理了。所以你必须执行Person.Include(x=> x.employer)来强制加载它。

立即加载当你确定想要一次获得多个实体时,例如你必须在同一页面上显示用户和用户详细信息,那么你应该使用急切加载。主动加载是单次点击数据库,加载相关实体。

延迟加载当你只能在页面上显示用户时,通过点击用户,你需要显示用户的详细信息,那么你需要使用延迟加载。延迟加载进行多次点击,以便在绑定/迭代相关实体时加载相关实体。

延迟加载 -在处理分页时很好,例如在页面加载时出现包含10个用户的用户列表,当用户向下滚动页面时,API调用会带来下一个10个用户。当你不想一次加载整个数据时,它是很好的,因为它会花费更多的时间,并会给一个糟糕的用户体验。

急切加载 -像其他人建议的那样,在关系不多的情况下,一次调用数据库即可获取整个数据

从搜索引擎优化的角度来看,延迟加载有助于保存资源,直到你加载图像,帮助减少加载时间,所以经常被用来提高网站加载速度。

然而,有时这会导致延迟谷歌的"第一次内容绘制"(FCP)指标,所以建议使用loading='eager'横幅图像和'above the fold'内容。特别是在主页上。

// Using LINQ and just referencing p.Employer will lazy load
// I am not at a computer but I know I have lazy loaded in one
// query with a single query call like below.
List<Person> persons = new List<Person>();
using(MyDbContext dbContext = new MyDbContext())
{
    persons = (
        from p in dbcontext.Persons
        select new Person{
            Name = p.Name,
            Email = p.Email,
            Employer = p.Employer
        }).ToList();
}

最好在可能的情况下使用即时加载,因为它可以优化应用程序的性能。

前:

Eager loading
var customers= _context.customers.Include(c=> c.membershipType).Tolist();
lazy loading

在模型客户必须定义

Public virtual string membershipType {get; set;}

所以当查询时,惰性加载加载所有引用对象的速度要慢得多,而急于加载只查询和选择相关的对象。