LINQ

18 questions found

What is the difference between First(), FirstOrDefault(), Single(), and SingleOrDefault()?

Intermediate
First() returns the first matching element or THROWS if none exists; FirstOrDefault() returns the first match or the type's DEFAULT value (like null or 0) if none exists; Single() requires EXACTLY ONE match (throws if zero OR more than one); SingleOrDefault() requires ZERO or ONE match (throws only if MORE than one), returning default for zero.
var numbers = new List<int> { 1, 2, 3 };
int first = numbers.First(n => n > 1);              // 2
int? firstOrNone = numbers.FirstOrDefault(n => n > 10); // 0 (default for int)
int single = numbers.Single(n => n == 2);            // 2 -- exactly one match required
Real-world example Using Single() to enforce that a lookup by unique ID returns EXACTLY one record, catching data integrity bugs if it somehow doesn't.

Common follow-ups: Why might using Single() instead of First() actually help CATCH a subtle data bug rather than just being 'more strict for no reason'?

Exception Handling

How does LINQ to Objects differ fundamentally from LINQ to Entities (Entity Framework), particularly regarding how the query is actually executed?

Advanced
LINQ to Objects compiles queries into regular, DIRECTLY-EXECUTABLE C# delegates that run in-process against in-memory collections; LINQ to Entities (via IQueryable<T>) instead builds an EXPRESSION TREE representing the query's structure, which Entity Framework TRANSLATES into SQL and executes on the DATABASE SERVER — meaning not every C# expression/method is translatable, and some LINQ code that works fine against a List<T> throws at runtime against a DbSet<T>.
IEnumerable<User> inMemory = users.Where(u => u.IsActive); // runs entirely in C#, in-process

IQueryable<User> fromDb = dbContext.Users.Where(u => u.IsActive); // translated to SQL: WHERE IsActive = 1
// dbContext.Users.Where(u => SomeComplexCSharpOnlyMethod(u)); // may throw: can't translate to SQL
Real-world example Debugging a runtime error where a LINQ query worked fine in a unit test against an in-memory List<T> but failed against the real Entity Framework DbSet<T>.

Common follow-ups: Why does calling .ToList() or .AsEnumerable() partway through an EF Core query change what CAN be used in the REMAINING LINQ chain?

Fundamentals

How would you write a custom LINQ extension method that integrates seamlessly with the standard method-chaining style, like a 'DistinctBy' before it existed natively?

Advanced
Write a generic extension method on IEnumerable<T> that internally uses a HashSet (often of the KEY, not the whole object) to track already-seen items, yielding only the FIRST occurrence for each unique key — implemented lazily with yield return so it composes correctly with the rest of a deferred LINQ chain.
public static IEnumerable<T> MyDistinctBy<T, TKey>(this IEnumerable<T> source, Func<T, TKey> keySelector) {
  var seenKeys = new HashSet<TKey>();
  foreach (var item in source) {
    if (seenKeys.Add(keySelector(item))) yield return item; // Add() returns false if already present
  }
}
var uniqueByEmail = users.MyDistinctBy(u => u.Email).ToList();
Real-world example Deduplicating a list of orders by customer ID, keeping only the first order per customer, before .NET 6 added native DistinctBy().

Common follow-ups: Why is it important that this custom extension method ALSO be implemented lazily (yield return), rather than eagerly building a List<T>?

Iterators & yield return

How does LINQ's Aggregate() method work, and how would you use it to implement a custom reduction not covered by Sum()/Average()/Count()?

Advanced
Aggregate() applies an accumulator function CUMULATIVELY across a sequence, carrying forward a running result from each step to the next — useful for custom reductions (like building a concatenated string, computing a running maximum with extra logic, or a custom fold) that don't match any of LINQ's specific built-in aggregate methods.
var words = new[] { "Hello", "World", "LINQ" };
string sentence = words.Aggregate((acc, word) => acc + " " + word);
// "Hello World LINQ"

int product = new[] { 1, 2, 3, 4 }.Aggregate(1, (acc, n) => acc * n); // 24, with a seed value
Real-world example Implementing a custom reduction, like computing a running maximum-so-far or concatenating a list into a single formatted string.

Common follow-ups: What's the difference between the overload of Aggregate() with a seed value versus the one without?

Functional Programming

How would you write an efficient LINQ query combining Join() with GroupBy() to replicate a SQL-style LEFT OUTER JOIN with aggregation?

Advanced
Use GroupJoin() (which pairs each element from the outer sequence with a GROUP of matching elements from the inner sequence, including an EMPTY group for no matches — mimicking a LEFT OUTER JOIN), then flatten and aggregate the grouped results as needed, unlike a regular Join() which behaves like an INNER JOIN and drops unmatched outer elements entirely.
var results = customers.GroupJoin(
    orders,
    customer => customer.Id,
    order => order.CustomerId,
    (customer, customerOrders) => new {
      customer.Name,
      OrderCount = customerOrders.Count() // 0 for customers with no matching orders, unlike an inner Join
    });
Real-world example Generating a report showing EVERY customer's order count, including customers with ZERO orders, mirroring a SQL LEFT JOIN with COUNT.

Common follow-ups: How does regular Join() (INNER JOIN semantics) behave differently for customers with no matching orders at all?

Collections

How would you optimize a LINQ-to-Entities query to avoid the classic 'N+1 query' performance problem when accessing related navigation properties?

Advanced
Use Include() (and ThenInclude() for nested relationships) to EAGERLY LOAD related entities in the SAME database query, instead of letting Entity Framework lazily issue a SEPARATE query for each related entity accessed individually inside a loop — the N+1 problem occurs when a loop over N parent entities triggers N additional queries for their related child entities.
// N+1 problem: triggers a SEPARATE query for EACH order's Customer, inside the loop
var orders = dbContext.Orders.ToList();
foreach (var order in orders) { Console.WriteLine(order.Customer.Name); } // 1 + N queries!

// Fixed with eager loading: ONE query total
var ordersFixed = dbContext.Orders.Include(o => o.Customer).ToList();
foreach (var order in ordersFixed) { Console.WriteLine(order.Customer.Name); } // just 1 query
Real-world example Fixing a slow API endpoint whose database query count scales linearly (and badly) with the number of returned records.

Common follow-ups: How would you detect an N+1 query problem occurring in a real application, using EF Core's logging or a profiling tool?

Design Patterns in C#

What is LINQ, and how does it simplify querying collections compared to writing manual loops?

Intermediate
LINQ (Language Integrated Query) lets you filter, transform, sort, and aggregate data using a concise, declarative, SQL-like syntax directly in C#, working consistently across in-memory collections (LINQ to Objects), databases via Entity Framework (LINQ to Entities), and XML -- instead of manually writing a loop with conditional logic to build a filtered result, you express the intent directly, and LINQ handles the iteration; a key related concept is deferred execution, where a LINQ query isn't actually run until its results are enumerated (like via ToList() or a foreach), letting the runtime optimize what actually gets executed.
// Manual loop
var evenNumbers = new List<int>();
foreach (var n in numbers) { if (n % 2 == 0) evenNumbers.Add(n); }

// Equivalent LINQ, more concise and declarative
var evenNumbers = numbers.Where(n => n % 2 == 0).ToList();

// Deferred execution: no filtering happens until .ToList() is actually called
var query = numbers.Where(n => n > 2);
var result = query.ToList(); // filtering runs HERE, not when 'query' was defined
Real-world example A reporting feature filters and groups a large in-memory list of transactions by category and date range using a single chained LINQ expression, replacing what would otherwise be several nested loops and temporary collections with a few readable lines.

Common follow-ups: What specific LINQ operations (GroupBy, Join, Aggregate) go beyond simple filtering?;Why does deferred execution sometimes cause a query to unexpectedly re-run and produce different results?

Streams & Lambdas;Comprehensions & Generators

What is the difference between IEnumerable<T>, IQueryable<T>, and List<T>, and how does choosing the wrong one hurt performance against a database?

Intermediate
IEnumerable<T> represents a sequence you iterate in memory -- when used against Entity Framework, any filtering applied to it happens AFTER the full dataset has already been pulled into memory, which is wasteful for large tables. IQueryable<T> instead builds an expression tree that Entity Framework translates into SQL, so filtering, sorting, and aggregation happen at the database level, only returning the rows that actually match. List<T> is a fully materialized, in-memory collection supporting fast indexed access and mutation, but by definition has already loaded everything it contains -- the practical rule is to keep queries as IQueryable<T> for as long as possible, only materializing to a List<T> once you're ready to actually use the final, filtered results.
// Inefficient: pulls ALL rows into memory, THEN filters
IEnumerable<User> users = dbContext.Users;
var adults = users.Where(u => u.Age >= 18); // filtering happens in memory, after loading everything

// Efficient: filter is translated to SQL and applied by the database
IQueryable<User> query = dbContext.Users.Where(u => u.Age >= 18);
var adults = query.ToList(); // only matching rows are ever retrieved
Real-world example A slow admin dashboard querying a million-row orders table via IEnumerable<T> (accidentally loading every row before filtering) is fixed by switching the query to IQueryable<T>, letting the database itself apply the WHERE clause and return only the handful of relevant rows.

Common follow-ups: How would you detect in code review that an IEnumerable-typed query is about to cause a full table scan?;What's the risk of calling .ToList() too early in a LINQ chain against Entity Framework?

SQL Queries;Diagnostics & Performance

Showing 11–18 of 18