Entity Framework - 使用Include/贪婪加载和延迟加载有什么区别?

16 浏览
0 Comments

Entity Framework - 使用Include/贪婪加载和延迟加载有什么区别?

我一直在努力熟悉Entity Framework。大部分都很简单,但是我有点困惑于使用Include方法进行急切加载和默认的延迟加载之间的区别。两者似乎都会加载相关的实体,因此表面上看它们似乎做相同的事情。我错过了什么吗?

admin 更改状态以发布 2023年5月23日
0
0 Comments

如果您来自SQL世界,请考虑JOIN。

如果您需要在网格中显示10个订单和下订单的客户,您有两个选择:

1)LAZY LOAD(=11个查询=慢执行效果)

EF将发出一条查询以检索订单,并为每个订单发出一条查询以检索客户数据。

Select * from order where order=1
+
10 x (Select * from customer where id = (order.customerId))

2)EAGER LOAD(=1个查询=高性能)

EF将发出单个查询以检索订单和客户,并使用JOIN。

Select * from orders INNER JOIN customers on orders.customerId=customer.Id where order=1

PS:当您从数据库中检索对象时,在上下文处于活动状态时,对象将存储在缓存中。
在我用LAZY LOAD制作的示例中,如果所有10个订单与同一客户相关,则您将只看到2个查询,因为当您要求EF检索对象时,EF将检查对象是否在缓存中,如果找到它,它将不会向DB发出另一个SQL查询。

0
0 Comments

假设您有两个实体之间存在一对多的关系:顾客和订单,其中每个顾客可以有多个订单。

当加载顾客实体时,Entity Framework 允许您选择急切地或惰性地加载顾客的订单集合。如果您选择急切加载订单集合,则在从数据库检索出一个顾客时,Entity Framework 会生成 SQL,该 SQL 会在一个查询中检索出顾客的信息和顾客的订单。然而,如果您选择惰性加载订单集合,则在从数据库检索出一个顾客时,Entity Framework 会生成仅拉取顾客信息的 SQL(如果您稍后在代码中访问顾客的订单集合,Entity Framework 将生成单独的 SQL 语句)。

确定何时使用急切加载和何时使用惰性加载完全取决于您希望对检索到的实体执行什么操作。如果您知道仅需要顾客的信息,则应该惰性加载订单集合(以便通过仅检索顾客信息来使 SQL 查询高效)。相反,如果您知道需要遍历顾客的订单,则应该急切地加载订单(这样一旦在代码中访问顾客的订单,您就可以节省额外的数据库访问)。

附:使用惰性加载时要非常小心,因为它可能会导致 N+1 问题。例如,假设您有一个显示客户及其订单列表的页面。但是,当获取订单时您决定使用惰性加载。当您迭代客户集合并迭代每个客户的订单时,您将为每个客户执行一次数据库访问,以惰性加载其订单集合。这意味着对于 N 个客户,您将有 N+1 个数据库访问(1 个数据库访问以加载所有客户,然后是 N 个数据库访问以加载它们每个的订单),而不是只有 1 个数据库访问(如果使用急切加载,则会在一次查询中检索所有客户及其订单)。

0