What's the difference between include/eager loading and lazy loading in Entity Framework?

eager-loading entity-framework lazy-loading

Question

I've been making an effort to get acquainted with the Entity Framework. The most of it sounds simple, however I'm not really sure what eager loading using the Include method and default slow loading are. On the surface, it seems like they both load related things, therefore they appear to be doing the same action. What am I overlooking?

1
18
8/17/2010 5:27:55 PM

Accepted Answer

Imagine that you have a one-to-many connection between two things called a customer and an order, where a customer may have many orders.

Entity Framework gives you the option to eager load or lazily load the Customer's Orders collection during entity loading. When you receive a Customer from the database, Entity Framework will produce SQL that fetches both the Customer's details and the Customer's Orders in one query if you choose to eager load the Orders collection. However, if you decide to lazy load the Orders collection, Entity Framework will create a separate SQL statement if you later access the Customer's Orders collection in your code. This is because when you retrieve a Customer from the database, Entity Framework will generate SQL that only pulls the Customer's information.

What you want to do with the things you obtain will determine whether to employ eager loading and when to utilize lazy loading. Lazy loading the Orders collection is recommended if you just want a Customer's information (so that the SQL query only needs to get the Customer's data). On the other hand, if you know you'll need to browse through a customer's orders, you should eager-load the orders (to avoid having to access the customer's orders again later in your code).

PS: Use lazy loading with extreme caution as it might result in the N+1 issue. Say, for illustration, that you have a page that lists Customers and their Orders. However, you choose to obtain the Orders via lazy-loading. You will make a database query for each Customer to lazy-load in their Orders collection when you loop over the Customers collection and then over each Customer's Orders. As a result, instead of only one database hit if you had utilized eager loading, you would have needed N+1 database hits for every N customers (1 database hit to load up all the Customers, then N database hits to load up each of their Orders) (which would have retrieved all Customers and their Orders in one query).

30
8/17/2010 5:39:54 PM

Popular Answer

Think about JOIN if you come from the realm of SQL.

There are two options if you need to display 10 orders together with the consumer who placed the purchase in a grid:

1) LASCIOUS LOAD (11 queries = SLOW PERFORMANCES)

To obtain the orders and the client information for each order, EF will fire out a query.

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

1) EAGER LOAD (one search = high performance)

To obtain the orders and customers using a JOIN, EF will issue a single query.

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

PS: The item is kept in a cache while the context is active when it is retrieved from the database. You will only notice 2 queries in the sample I created using LAZY LOAD, if the same client is involved in each of the 10 orders, because when you ask EF to fetch an item, EF will first check to see whether the object is in the cache and if it is, it won't issue a second SQL query to the database.



Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow