关于预加载、显式加载和延迟加载之间的区别,我搜索了很多。 我想了解这三者的行为,以便能够决定何时使用每一个。 所以经过大量搜索,我只是想确保我理解正确。因为,如果我误解了什么,我会很感激有人纠正我。
1_eager 加载:
eager 加载将在单个查询中检索,因为它将被转换为包含 join 操作的 sql 查询。这允许缓存检索到的数据,从而提高应用程序性能。这就像内存消耗和数据库行程(在数据库服务器和应用程序服务器之间)之间的权衡。
所以预加载对性能有好处,但如果我想检索大量数据,它不是一个好的选择: 例如,如果我有一个用户列表,每个用户都有一个评论列表。在这种情况下,由于内存消耗大,预加载将不是一个好的选择。
2-延迟加载
延迟加载不会像急切加载那样转换为包含 join 的 sql 查询,而是会转换为一组 select 查询,例如,如果我有一个用户列表,每个用户都有一个评论列表sql 查询将是这样的:
Select * from Users (to retrive all the users)
//for each user
Select * from Reviews where Reviews.UserId =userId;
//will need 1+n sql quries, where n is the number of users
这不会导致大量的内存消耗,反而会增加数据库的往返次数(数据库服务器和应用服务器之间)。所以在性能上不如eager loading,但是对于数据量大的情况下,lazy loading比较好用,可以避免内存的大量消耗。所以对于上面的例子,如果用户数量很大,使用延迟加载比急切加载更好。
3-显式加载:
显式加载类似于延迟加载,但它只适用于单个实体。所以如果我想在列表中使用它,我必须创建一个 for 循环来遍历每个实体。
所以,例如假设我只想在传递用户id时获取用户的相关评论,最好的方法是使用: _显式加载:因为延迟加载会在每次从数据库中检索用户时加载相关评论(在这种情况下,我只需要在传递 id 时检索它)
public async Task<User> GetUserById(int id)
{
var user = _context.User.Find(id);
var userWithReviews =context.Entry(user).
.Collection(b => b.Reviews).load();
return userWithReviews;
}
_或使用简单的选择:因为预加载使用连接(我知道 join 比 select 操作成本更高)
public async Task<UserAndReviews> GetUserById(int id)
{
UserAndReviews userAndReviws = new UserAndReviews();
var user = await _context.User.FindByIdAsync(id);
var Reviews =await context.Reviews.where(r=>r.UserId =id).ToListAsync();
userAndReviws.user = user;
userAndReviws.Reviews =Reviews;
return userAndReviws;
}
这是我经过大量搜索后的理解,如果我有任何误解,我将不胜感激。
提前致谢。