LINQ (Language INtegrated Query)
LINQ stands for Language INtegrated Query. LINQ is one of the best features of .NET.
LINQ allows developers to write concise, readable queries directly in C# (or other .NET languages) to work with collections, databases, XML, and other data sources.
While other languages have their version of LINQ, it remains a key feature that enhances productivity and code clarity in .NET.
Example: Employee Data Query
Imagine you have an Employee
object, and you need to:
- Get the names of all employees who are earning over $100,000.
- Display these names on the page, sorted in order.
Solution Using For Loops and Sorting
Before LINQ, you would have to do something like this:
List<Employee> employees = GetEmployees();
List<Employee> highEarners = new List<Employee>();
foreach (var employee in employees)
{
if (employee.Salary > 100000)
{
highEarners.Add(employee);
}
}
highEarners.Sort((emp1, emp2) => emp1.Name.CompareTo(emp2.Name));
foreach (var highEarner in highEarners)
{
Console.WriteLine(highEarner.Name);
}
With LINQ, you can drastically simplify this code:
Lambda Syntax:
var highEarners = employees
.Where(e => e.Salary > 100000)
.OrderBy(e => e.Name)
.Select(e => e.Name);
foreach (var name in highEarners)
{
Console.WriteLine(name);
}
Query Syntax:
var highEarners = from e in employees
where e.Salary > 100000
orderby e.Name
select e.Name;
foreach (var name in highEarners)
{
Console.WriteLine(name);
}
Technologies That Make LINQ Possible
LINQ is built on a combination of several core .NET technologies:
- Generics: Allows LINQ to work with collections of any type.
IEnumerable<T>
: LINQ queries work on any collection that implements this interface.- Extension Methods: LINQ uses extension methods like
Where()
,OrderBy()
, andSelect()
to add query capabilities to collections. - Lambda Expressions: Lambda expressions provide the logic for filtering, sorting, and transforming data in LINQ queries.
How Lazy Evaluation Works with IEnumerable<T>
and LINQ
In the context of IEnumerable<T>
, methods that operate on collections like Select
, Where
, and Take
do not immediately execute when called. Instead, they set up a query pipeline, and the actual iteration (evaluation) happens only when you access the elements—for example, by using a foreach
loop or calling a terminal operation like ToList()
.
This "deferred execution" model allows for efficient processing of potentially large collections without consuming memory unnecessarily by generating all elements up front.
public class Example
{
public static void Main()
{
var numbers = new[] { 1, 2, 3, 4, 5 };
var query = numbers.Where(n => n % 2 == 0);
Console.WriteLine("Query is defined, but not executed yet.");
foreach (var number in query)
{
Console.WriteLine(number); // Only now is the query executed
}
}
}
- In the example,
numbers.Where(n => n % 2 == 0)
defines the query but does not execute it immediately. - The query is only evaluated when the
foreach
loop iterates over the sequence. This is what makes the query "lazy."
ToList()
and ToArray()
ToList
and ToArray
are methods that make an IEnumerable<T>
into a List<T>
or array of that type. It forces an otherwise "lazy" sequence into materialization.
public class Example
{
public static void Main()
{
var numbers = new[] { 1, 2, 3, 4, 5 };
var query = numbers.Where(n => n % 2 == 0);
Console.WriteLine("Query is defined, but not executed yet.");
var asList = query.ToList();
//now it's executed and those values are officially in memory!
}
}
Query Syntax vs Lambda Syntax
Query Syntax: This syntax is closer to SQL and is often easier to read for those familiar with traditional SQL databases.
var result = from item in collection
where item.Condition == true
select item;
Lambda Syntax: This is more concise and can chain multiple operations. It's more commonly used among developers who prefer functional programming concepts.
var result = collection
.Where(item => item.Condition == true); //the select is not needed here - it's implied
Both syntaxes ultimately compile to the same code, so it's a matter of personal preference or readability when choosing which to use.
🌶️🌶️🌶️ Spencer exclusively uses lambda syntax, and 99% of code he sees in the wild is lambda syntax. We'll be focusing on using LINQ with lambda syntax only.