Explain Codes LogoExplain Codes Logo

What does Include() do in LINQ?

sql
include
eager-loading
lazy-loading
Nikita BarsukovbyNikita Barsukov·Aug 20, 2024
TLDR

The Include() function in LINQ eagerly loads related entities, mitigating the N+1 query problem. It adds related data to your initial query, effectively acting as a SQL JOIN.

var blogs = context.Blogs.Include(b => b.Posts).ToList(); // Carries Posts along with Blogs in one trip

The above line of code fetches Blogs and their respective Posts in a single query, increasing data retrieval efficiency.

Maximizing EF performance with Include()

Include() can enhance performance by reducing round-trips to your database. It folds related entities into the main query, preempting additional queries synonymous to "Lazy Loading". Therefore, strategically using Include() cuts down on the overall database queries, eventually accelerating your operations.

Eager loading vs. Lazy loading: The battle

In Entity Framework, two prevalent loading mechanisms are at play: Eager Loading and Lazy Loading. Eager Loading fetches related entities as part of the original query, reducing DB round-trips. Conversely, Lazy Loading waits until related entities are explicitly queried, potentially causing multiple database hits."Patience is a virtue, but not for your DB server!"

// Eager Loading var orders = context.Customers.Include(c => c.Orders).ToList(); // "Get ready to ship 'em all!" // Lazy Loading (if enabled) var customer = context.Customers.FirstOrDefault(); var orders = customer.Orders; // "Wait, I forgot the orders. BRB!"

Deep Dive: Nested joys with ThenInclude()

To add to its prowess, Include() couples with ThenInclude() to fetch nested relationships, achieving efficient query performance, even with deeply nested data structures.

var customers = context.Customers .Include(c => c.Orders) .ThenInclude(o => o.OrderDetails) .ToList(); // It's like an unending "Russian doll" query

Beware: The Include() Pitfall

While Include() is undoubtedly powerful, it can be a double-edged sword. Indiscriminate usage may lead to redundant data retrieval, affecting performance. Remember, EF is not an "All-You-Can-Eat buffet." Include only what you'll consume!

Finer strategies to optimize Include()

Include() offers various possibilities to optimize your queries:

  • Selective Loading: Use Select() to fetch only necessary fields.
  • Projection: Reduce data fetched by projecting into DTOs.
  • Filtering: Apply Where() for fetching precise related data.
// Selective loading with Projection var customers = context.Customers .Include(c => c.Orders) .Select(c => new CustomerDto { Name = c.Name, OrderCount = c.Orders.Count() // Only Count, 'coz size matters! }) .ToList();