DEV Community

davinceleecode
davinceleecode Subscriber

Posted on

LINQ in Entity Framework You Should Know 🧐

Entity Framework (EF) is a powerful ORM (Object-Relational Mapper) for .NET, and LINQ (Language Integrated Query) is the primary way to interact with EF data models. Mastering LINQ not only helps you write clean, expressive, and efficient queries but also prevents common pitfalls like performance issues.


1. Defer Execution and IQueryable

EF queries using IQueryable are not executed immediately. Instead, they are built into an expression tree and executed only when iterated (e.g., via ToList(), FirstOrDefault(), etc.).

var query = _context.Orders.Where(o => o.CustomerId == 5); // No DB hit yet
var list = query.ToList(); // Now the SQL query is sent
Enter fullscreen mode Exit fullscreen mode

✅ Rule:

Always build your full query before calling .ToList() or any terminal operator.


2. Avoid Calling .ToList() Too Early

Calling .ToList() early materializes the result and breaks query composition, which means:

  • You lose the ability to add filters, sorting, and includes efficiently.
  • It might bring more data into memory than necessary.

🚫 Bad:

var orders = _context.Orders.ToList();
var filtered = orders.Where(o => o.Total > 100); // This runs in memory
Enter fullscreen mode Exit fullscreen mode

✅ Good:

var filtered = _context.Orders.Where(o => o.Total > 100); // Query runs in SQL
Enter fullscreen mode Exit fullscreen mode

3. Use Select to Project Data

Avoid selecting entire entities if you only need a few fields. This improves performance.
🚫 Bad:

var customers = _context.Customers.ToList(); // Loads all columns
Enter fullscreen mode Exit fullscreen mode

✅ Good:

var names = _context.Customers.Select(c => c.Name).ToList();
Enter fullscreen mode Exit fullscreen mode

4. Eager Loading with .Include()

To avoid the N+1 problem, use .Include() to load related data.

var orders = _context.Orders.Include(o => o.Customer).ToList();
Enter fullscreen mode Exit fullscreen mode

Without .Include(), accessing order.Customer will trigger separate queries if lazy loading is enabled.


5. Pagination Using Skip and Take

Efficiently handle large datasets using .Skip() and .Take() for pagination.

int page = 2;
int pageSize = 10;

var pagedOrders = _context.Orders
    .OrderBy(o => o.Id)
    .Skip((page - 1) * pageSize)
    .Take(pageSize)
    .ToList();
Enter fullscreen mode Exit fullscreen mode

6. Query Filters and Reusability

You can reuse LINQ query definitions:

var query = _context.Orders.Where(o => o.Status == "Active");

var top10 = query.OrderBy(o => o.Date).Take(10).ToList();
var count = query.Count();
Enter fullscreen mode Exit fullscreen mode

7. Avoid N+1 Query Problem

This happens when you loop through a list and access navigation properties, causing multiple DB calls.
🚫 Bad:

var orders = _context.Orders.ToList();
foreach (var order in orders)
{
    Console.WriteLine(order.Customer.Name); // Triggers extra query per order
}
Enter fullscreen mode Exit fullscreen mode

✅ Good:

var orders = _context.Orders.Include(o => o.Customer).ToList();
Enter fullscreen mode Exit fullscreen mode

8. Use Any() Instead of Count() for Existence Checks

var exists = _context.Orders.Any(o => o.Status == "Pending");
Enter fullscreen mode Exit fullscreen mode

Using Count() to check existence is less efficient.


Bonus Tips

🚫 No SQL is sent to the database until you do something like:

.ToList() / .ToListAsync()
.FirstOrDefault() / .FirstOrDefaultAsync()
.Count() / .CountAsync()
.Any() / .AnyAsync()
.Sum() / etc.
Enter fullscreen mode Exit fullscreen mode

Only then will EF Core execute the SQL against the database.

Final Tips:

  • Use AsNoTracking() when you only need to read data (for performance).
  • Prefer method syntax over query syntax for consistency.
  • Profile queries using tools like EF Profiler or SQL Profiler if you're concerned about performance.

By following these LINQ best practices in Entity Framework, you can write performant, maintainable, and cleaner data access code in your applications.

If you found this helpful, consider supporting my work at ☕ Buy Me a Coffee.

Top comments (0)