懒惰加载与急切加载

在什么情况下,渴望加载比延迟加载更有益?

实体框架中的延迟加载是加载和访问相关实体时发生的默认现象。然而,急加载是指力加载的实践中所有这些关系。

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

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

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

如果有人能向我解释在什么情况下渴望加载比懒惰加载更有益,我将非常感激,而且我们为什么要使用它,而懒惰加载是一种更加资源友好的加载方式呢?

153276 次浏览

Lazy loading will produce several SQL calls while Eager loading may load data with one "more heavy" call (with joins/subqueries).

For example, If there is a high ping between your web and sql servers you would go with Eager loading instead of loading related items 1-by-1 with lazy Loading.

I think it is good to categorize relations like this

When to use eager loading

  1. In "one side" of one-to-many relations that you sure are used every where with main entity. like User property of an Article. Category property of a Product.
  2. Generally When relations are not too much and eager loading will be good practice to reduce further queries on server.

When to use lazy loading

  1. Almost on every "collection side" of one-to-many relations. like Articles of User or Products of a Category
  2. You exactly know that you will not need a property instantly.

Note: like Transcendent said there may be disposal problem with lazy loading.

Consider the below situation

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();
}
}

Now after this method is called, you cannot lazy load the Employer entity anymore. Why? because the db object is disposed. So you have to do Person.Include(x=> x.employer) to force that to be loaded.

// 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: Eager Loading helps you to load all your needed entities at once. i.e. related objects (child objects) are loaded automatically with its parent object.

When to use:

  1. Use Eager Loading when the relations are not too much. Thus, Eager Loading is a good practice to reduce further queries on the Server.
  2. Use Eager Loading when you are sure that you will be using related entities with the main entity everywhere.

Lazy Loading: In case of lazy loading, related objects (child objects) are not loaded automatically with its parent object until they are requested. By default LINQ supports lazy loading.

When to use:

  1. Use Lazy Loading when you are using one-to-many collections.
  2. Use Lazy Loading when you are sure that you are not using related entities instantly.

NOTE: Entity Framework supports three ways to load related data - eager loading, lazy loading and explicit loading.

Eager Loading When you are sure that want to get multiple entities at a time, for example you have to show user, and user details at the same page, then you should go with eager loading. Eager loading makes single hit on database and load the related entities.

Lazy loading When you have to show users only at the page, and by clicking on users you need to show user details then you need to go with lazy loading. Lazy loading make multiple hits, to get load the related entities when you bind/iterate related entities.

It is better to use eager loading when it is possible, because it optimizes the performance of your application.

ex-:

Eager loading


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


lazy loading

In model customer has to define

Public virtual string membershipType {get; set;}

So when querying lazy loading is much slower loading all the reference objects, but eager loading query and select only the object which are relevant.

Lazy loading - is good when handling with pagination like on page load list of users appear which contains 10 users and as the user scrolls down the page an API call brings next 10 users. It's good when you don't want to load the entire data at once as it would take more time and would give a bad user experience.

Eager loading - is good as other people suggested when there are not many relations and fetch entire data at once in a single call to the database