C#: LINQ Queries

1. LINQ Concepts and Motivation

LINQ (Language Integrated Query) is a built-in data query language in C# that allows you to query different data sources (collections, databases, XML, etc.) using a unified syntax. Before LINQ, querying different data sources required learning different APIs — LINQ solves this problem.

▶ Example

CSHARP
using System;
using System.Linq;

int[] numbers = { 5, 12, 3, 21, 8, 15 };

var result = from n in numbers
             where n > 10
             select n;

foreach (var n in result)
{
    Console.WriteLine(n);
}
▶ Try it Yourself
TEXT 📖 Display only
12
21
15

2. Query Syntax vs Method Syntax

LINQ provides two styles: Query Syntax and Method Syntax. Both are functionally equivalent. Method Syntax is more commonly used in practice because it supports more operators and allows concise chained calls.

▶ Example

CSHARP
using System;
using System.Linq;

int[] numbers = { 5, 12, 3, 21, 8, 15 };

var querySyntax = from n in numbers
                  where n > 10
                  orderby n
                  select n;

var methodSyntax = numbers.Where(n => n > 10).OrderBy(n => n);

Console.WriteLine("Query syntax: " + string.Join(", ", querySyntax));
Console.WriteLine("Method syntax: " + string.Join(", ", methodSyntax));
▶ Try it Yourself
TEXT 📖 Display only
Query syntax: 12, 15, 21
Method syntax: 12, 15, 21

3. from / where / select / orderby / group

The core query syntax clauses: from specifies the data source and range variable, where filters, select projects results, orderby sorts, and group ... by groups.

▶ Example

CSHARP
using System;
using System.Linq;

string[] names = { "Alice", "Bob", "Anna", "Charlie", "Amy" };

var result = from name in names
             where name.StartsWith("A")
             orderby name.Length
             select name;

foreach (var name in result)
{
    Console.WriteLine(name);
}
▶ Try it Yourself
TEXT 📖 Display only
Amy
Anna
Alice

(1) group by Example

CSHARP
using System;
using System.Linq;

var students = new[]
{
    new { Name = "Zhang", Grade = "A" },
    new { Name = "Li", Grade = "B" },
    new { Name = "Wang", Grade = "A" },
    new { Name = "Zhao", Grade = "C" },
    new { Name = "Sun", Grade = "B" }
};

var groups = from s in students
             group s by s.Grade into g
             select new { Grade = g.Key, Count = g.Count() };

foreach (var g in groups)
{
    Console.WriteLine($"Grade {g.Grade}: {g.Count} student(s)");
}
TEXT 📖 Display only
Grade A: 2 student(s)
Grade B: 2 student(s)
Grade C: 1 student(s)

4. Common Operators

Commonly used LINQ operators in method syntax:

Operator Purpose
Where Filter elements
Select Project/transform
OrderBy / OrderByDescending Sort ascending/descending
ThenBy Secondary sort
GroupBy Group elements
First / FirstOrDefault Get first element
Single / SingleOrDefault Get the only element
Count Count elements
Any Check if any element exists
All Check if all elements satisfy condition
Sum / Average Sum / average
Min / Max Minimum / maximum
Skip / Take Skip / take specified number
Distinct Remove duplicates
ToList / ToArray / ToDictionary Convert to collection

▶ Example

CSHARP
using System;
using System.Linq;

int[] numbers = { 3, 7, 2, 9, 5, 7, 3, 8 };

Console.WriteLine("Where > 5: " + string.Join(", ", numbers.Where(n => n > 5)));
Console.WriteLine("Select x2: " + string.Join(", ", numbers.Select(n => n * 2)));
Console.WriteLine("OrderBy: " + string.Join(", ", numbers.OrderBy(n => n)));
Console.WriteLine("OrderByDescending: " + string.Join(", ", numbers.OrderByDescending(n => n)));
Console.WriteLine("Distinct: " + string.Join(", ", numbers.Distinct()));
Console.WriteLine("First: " + numbers.First());
Console.WriteLine("FirstOrDefault > 10: " + numbers.FirstOrDefault(n => n > 10));
Console.WriteLine("Count > 5: " + numbers.Count(n => n > 5));
Console.WriteLine("Any > 8: " + numbers.Any(n => n > 8));
Console.WriteLine("All > 1: " + numbers.All(n => n > 1));
Console.WriteLine("Sum: " + numbers.Sum());
Console.WriteLine("Average: " + numbers.Average());
Console.WriteLine("Min: " + numbers.Min());
Console.WriteLine("Max: " + numbers.Max());
Console.WriteLine("Skip 3 Take 2: " + string.Join(", ", numbers.Skip(3).Take(2)));
▶ Try it Yourself
TEXT 📖 Display only
Where > 5: 7, 9, 7, 8
Select x2: 6, 14, 4, 18, 10, 14, 6, 16
OrderBy: 2, 3, 3, 5, 7, 7, 8, 9
OrderByDescending: 9, 8, 7, 7, 5, 3, 3, 2
Distinct: 3, 7, 2, 9, 5, 8
First: 3
FirstOrDefault > 10: 0
Count > 5: 4
Any > 8: True
All > 1: True
Sum: 44
Average: 5.5
Min: 2
Max: 9
Skip 3 Take 2: 9, 5

5. LINQ with List and Array

LINQ works on any object that implements the IEnumerable<T> interface, including List<T> and arrays T[].

▶ Example

CSHARP
using System;
using System.Collections.Generic;
using System.Linq;

List```<string>``` fruits = new List```<string>``` { "apple", "banana", "cherry", "date" };

var longNames = fruits.Where(f => f.Length > 5).Select(f => f.ToUpper());
Console.WriteLine("List query: " + string.Join(", ", longNames));

int[] scores = { 88, 72, 95, 60, 85 };
var topScores = scores.Where(s => s >= 85).OrderByDescending(s => s);
Console.WriteLine("Array query: " + string.Join(", ", topScores));
▶ Try it Yourself
TEXT 📖 Display only
List query: BANANA, CHERRY
Array query: 95, 88, 85

6. LINQ with Dictionary

When using LINQ on a dictionary, each element is a KeyValuePair<TKey, TValue>, accessed via .Key and .Value.

▶ Example

CSHARP
using System;
using System.Collections.Generic;
using System.Linq;

var prices = new Dictionary`<string, decimal>`
{
    { "Apple", 5.5m },
    { "Banana", 3.2m },
    { "Orange", 7.8m },
    { "Grape", 12.0m }
};

var expensive = prices.Where(kv => kv.Value > 5m)
                      .OrderByDescending(kv => kv.Value)
                      .Select(kv => $"{kv.Key}: {kv.Value}");

foreach (var item in expensive)
{
    Console.WriteLine(item);
}

var priceDict = prices.ToDictionary(kv => kv.Key, kv => kv.Value * 2);
Console.WriteLine("Doubled orange price: " + priceDict["Orange"]);
▶ Try it Yourself
TEXT 📖 Display only
Grape: 12.0
Orange: 7.8
Apple: 5.5
Doubled orange price: 15.6

7. Deferred Execution vs Immediate Execution

LINQ queries are deferred by default: defining a query does not execute it — the query only runs when you iterate over the results (e.g., with foreach). Calling methods like ToList(), ToArray(), Count(), or First() triggers immediate execution.

▶ Example

CSHARP
using System;
using System.Collections.Generic;
using System.Linq;

var numbers = new List```<int>``` { 1, 2, 3 };

var query = numbers.Where(n => n > 1);

numbers.Add(4);
numbers.Add(5);

Console.WriteLine("Deferred execution includes elements added later:");
foreach (var n in query)
{
    Console.WriteLine(n);
}

var immediate = numbers.Where(n => n > 1).ToList();

numbers.Add(6);

Console.WriteLine("Immediate execution does not include 6 added later:");
foreach (var n in immediate)
{
    Console.WriteLine(n);
}
▶ Try it Yourself
TEXT 📖 Display only
Deferred execution includes elements added later:
2
3
4
5
Immediate execution does not include 6 added later:
2
3
4
5

💡 Deferred execution means iterating over query results recalculates each time. If you need to use results multiple times, call ToList() to cache them.


8. IQueryable vs IEnumerable

IEnumerable<T> is used for in-memory collection queries (LINQ to Objects), while IQueryable<T> is used for remote data source queries (e.g., databases). It can translate expression trees into query languages like SQL and execute them server-side.

▶ Example

CSHARP
using System;
using System.Collections.Generic;
using System.Linq;

List```<int>``` data = new List```<int>``` { 10, 20, 30, 40, 50 };

IEnumerable```<int>``` enumerableQuery = data.Where(n => n > 25);
IQueryable```<int>``` queryableQuery = data.AsQueryable().Where(n => n > 25);

Console.WriteLine("IEnumerable result: " + string.Join(", ", enumerableQuery));
Console.WriteLine("IQueryable result: " + string.Join(", ", queryableQuery));
Console.WriteLine("IQueryable expression: " + queryableQuery.Expression);
▶ Try it Yourself
TEXT 📖 Display only
IEnumerable result: 30, 40, 50
IQueryable result: 30, 40, 50
IQueryable expression: System.Collections.Generic.List`1[System.Int32].Where(n => (n > 25))

⚠️ When using ORMs like EF Core, IQueryable executes filtering on the database side, while IEnumerable loads all data into memory first then filters — the performance difference can be significant.

❓ FAQ

Q Which is better — query syntax or method syntax?
A Method syntax is more commonly used, supports all operators, and allows concise chained calls. Query syntax only supports some operators but can be more readable for complex join/group operations.
Q What is the difference between FirstOrDefault and First?
A First throws an exception when no element is found; FirstOrDefault returns the default value (null for reference types, 0 for value types). Prefer FirstOrDefault in most cases.
Q What is the difference between Single and First?
A Single requires the sequence to have exactly one matching element — it throws if there are more than one. First simply returns the first matching element.
Q Why does iterating LINQ results twice execute the query twice?
A Because of deferred execution, each iteration recalculates. Use ToList() to cache results and avoid redundant computation.
Q How to choose between IQueryable and IEnumerable?
A Use IQueryable for database queries so SQL executes server-side; use IEnumerable for in-memory collections.

📖 Summary

📝 Exercises

  1. Given int[] nums = { 34, 7, 21, 56, 12, 89, 3 }, use method syntax to find all even numbers greater than 20 in descending order and output the result
  2. Define a student list (name, age, class), use LINQ to group by class and output the number of students in each class
  3. Create a Dictionary<string, int> storing product names and inventory, use LINQ to find product names with inventory less than 10, and convert to List<string>
  4. Write code demonstrating deferred execution: define a query then modify the original collection, observe whether the iteration result includes new elements; then use ToList() to contrast with immediate execution behavior
  5. Explain why IQueryable is more efficient than IEnumerable in EF Core in one sentence
Web-Tutorial.com

Web-Tutorial Tech Team

A team of developers maintaining programming tutorials. Each tutorial is written and reviewed by developers with expertise in that field. We work to keep our content accurate and reliable — if you spot an issue, please let us know.

100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏