Paramclasses Academy - Blog

Tutorials Details

←
Post 24 of 30
→

What is LINQ in C#: Filter, Sort and Query Data with Practical Examples ?

What is LINQ in C#: Filter, Sort and Query Data with Practical Examples ?

October 26, 2026

Introduction

LINQ (Language Integrated Query) is a powerful feature in C# that allows developers to query and manipulate data using a consistent, readable syntax.

With LINQ, you can filter records, sort collections, select specific properties, group data, calculate totals, and search for matching elements without writing lengthy loops for every operation.

LINQ works with different data sources, including arrays, lists, collections, XML, and databases through technologies such as Entity Framework Core.

In this tutorial, you will learn the fundamentals of LINQ, understand query syntax and method syntax, and explore practical examples that demonstrate how LINQ simplifies everyday programming tasks.

1. What Is LINQ in C#?

LINQ stands for Language Integrated Query. It integrates querying capabilities directly into C#.

Without LINQ, developers often write loops and conditional statements to find, filter, or transform data. LINQ provides methods and query expressions that make these operations more concise and readable.

Example Without LINQ

Suppose you have a list of numbers and want to find numbers greater than 10.

using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        List<int> numbers = new List<int>
        {
            5, 12, 8, 20, 3, 15
        };

        foreach (int number in numbers)
        {
            if (number > 10)
            {
                Console.WriteLine(number);
            }
        }
    }
}

Output:

12
20
15

The Same Example Using LINQ

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

class Program
{
    static void Main()
    {
        List<int> numbers = new List<int>
        {
            5, 12, 8, 20, 3, 15
        };

        var result = numbers.Where(n => n > 10);

        foreach (int number in result)
        {
            Console.WriteLine(number);
        }
    }
}

Output:

12
20
15

The Where() method filters the collection according to the specified condition.

The expression n => n > 10 is a lambda expression. It means that each element is represented by n, and the condition checks whether it is greater than 10.

2. Why Is LINQ Important?

LINQ helps developers write cleaner and more maintainable data-processing code.

Its main benefits include:

  • Readable code: Express filtering and sorting operations clearly.

  • Less repetitive code: Reduce boilerplate loops for common operations.

  • Type safety: C# checks types during compilation.

  • Multiple data sources: Query in-memory collections and supported external data sources.

  • Composable operations: Combine filtering, sorting, grouping, and projection.

  • Integration with C#: Use familiar language features and lambda expressions.

LINQ does not automatically make every operation faster. Performance depends on the data source, query structure, execution strategy, and amount of data being processed.

3. Two Ways to Write LINQ Queries

C# supports two main styles of writing LINQ queries.

A. Method Syntax

Method syntax uses extension methods such as Where(), Select(), OrderBy(), and GroupBy().

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

This example filters numbers greater than 10 and sorts the results in ascending order.

B. Query Syntax

Query syntax resembles SQL and uses keywords such as from, where, orderby, and select.

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

Both examples express the same filtering and sorting operations.

Important: Query syntax is translated by the C# compiler into method calls. Some operations, such as Count(), Sum(), and FirstOrDefault(), are typically written using method syntax.

4. The Where() Method: Filtering Data

The Where() method selects elements that satisfy a condition.

Example: Filter Even Numbers

using System;
using System.Linq;

class Program
{
    static void Main()
    {
        int[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8 };

        var evenNumbers = numbers.Where(n => n % 2 == 0);

        foreach (int number in evenNumbers)
        {
            Console.WriteLine(number);
        }
    }
}

Output:

2
4
6
8

Example: Filter Employees by Salary

using System;
using System.Linq;

class Employee
{
    public string Name { get; set; } = "";
    public decimal Salary { get; set; }
}

class Program
{
    static void Main()
    {
        Employee[] employees =
        {
            new Employee { Name = "Amit", Salary = 30000 },
            new Employee { Name = "Priya", Salary = 45000 },
            new Employee { Name = "Rahul", Salary = 25000 },
            new Employee { Name = "Neha", Salary = 60000 }
        };

        var result = employees
            .Where(e => e.Salary >= 40000);

        foreach (var employee in result)
        {
            Console.WriteLine(
                $"{employee.Name}: {employee.Salary}");
        }
    }
}

Output:

Priya: 45000
Neha: 60000

This example demonstrates how LINQ can filter objects using their properties rather than just numbers.

5. The Select() Method: Transforming Data

The Select() method projects each element into a new form. You can select a property, calculate a value, or create a new object.

Example: Select Names from Employees

using System;
using System.Linq;

class Program
{
    static void Main()
    {
        string[] names =
        {
            "Amit", "Priya", "Rahul", "Neha"
        };

        var result = names.Select(name => name.ToUpperInvariant());

        foreach (string name in result)
        {
            Console.WriteLine(name);
        }
    }
}

Output:

AMIT
PRIYA
RAHUL
NEHA

Example: Select Specific Properties

var result = employees.Select(e => new
{
    e.Name,
    e.Salary
});

This creates an anonymous object for each employee containing only the selected properties.

Use Where() when you want to decide which elements to keep. Use Select() when you want to decide what each element should become.

6. Sorting Data with OrderBy() and OrderByDescending()

LINQ provides methods for sorting collections.

  • OrderBy() sorts in ascending order.

  • OrderByDescending() sorts in descending order.

  • ThenBy() adds a secondary ascending sort.

  • ThenByDescending() adds a secondary descending sort.

Example: Sort Numbers

using System;
using System.Linq;

class Program
{
    static void Main()
    {
        int[] numbers = { 50, 10, 40, 20, 30 };

        var ascending = numbers.OrderBy(n => n);
        var descending = numbers.OrderByDescending(n => n);

        Console.WriteLine("Ascending:");

        foreach (int n in ascending)
        {
            Console.WriteLine(n);
        }

        Console.WriteLine("Descending:");

        foreach (int n in descending)
        {
            Console.WriteLine(n);
        }
    }
}

Output:

Ascending:
10
20
30
40
50
Descending:
50
40
30
20
10

Example: Sort Employees by Salary

var result = employees
    .OrderByDescending(e => e.Salary);

foreach (var employee in result)
{
    Console.WriteLine(
        $"{employee.Name}: {employee.Salary}");
}

This returns employees in descending salary order.

For multiple sorting conditions, you can write:

var result = employees
    .OrderBy(e => e.Name)
    .ThenByDescending(e => e.Salary);

The employee names are sorted first, and salary is used as a secondary key when names compare equally.

7. Searching with First(), FirstOrDefault(), Single(), and Any()

LINQ provides several methods for finding elements. They differ in their behavior when there are no matches or multiple matches.

Method Behavior
First() Returns the first matching element; throws if none exists
FirstOrDefault() Returns the first match or the default value if none exists
Single() Requires exactly one matching element; throws otherwise
SingleOrDefault() Returns the default value if none exists; throws if multiple matches exist
Any() Returns true if at least one element matches
Contains() Checks whether a collection contains a specified value

Example: Find a Number

using System;
using System.Linq;

class Program
{
    static void Main()
    {
        int[] numbers = { 10, 20, 30, 40, 50 };

        int first = numbers.First(n => n > 25);

        Console.WriteLine(first);

        bool exists = numbers.Any(n => n == 40);

        Console.WriteLine(exists);
    }
}

Output:

30
True

When Should You Use FirstOrDefault()?

Use FirstOrDefault() when no match is a valid outcome and you want to handle it without an exception.

int? result = numbers
    .Where(n => n > 100)
    .Select(n => (int?)n)
    .FirstOrDefault();

if (result.HasValue)
{
    Console.WriteLine(result.Value);
}
else
{
    Console.WriteLine("No matching number found.");
}

The nullable integer makes the absence of a matching value explicit. For reference types, the default result is usually null; for non-nullable value types such as int, it is typically 0.

8. Counting and Calculating with LINQ

LINQ supports common aggregate operations.

Method Purpose
Count() Counts elements
Sum() Calculates a total
Average() Calculates an average
Min() Finds the minimum
Max() Finds the maximum

Example: Calculate Total, Average, Minimum, and Maximum

using System;
using System.Linq;

class Program
{
    static void Main()
    {
        int[] marks = { 75, 80, 65, 90, 85 };

        Console.WriteLine($"Count: {marks.Count()}");
        Console.WriteLine($"Total: {marks.Sum()}");
        Console.WriteLine($"Average: {marks.Average()}");
        Console.WriteLine($"Minimum: {marks.Min()}");
        Console.WriteLine($"Maximum: {marks.Max()}");
    }
}

Output:

Count: 5
Total: 395
Average: 79
Minimum: 65
Maximum: 90

Be careful when aggregating empty collections. Some aggregate methods, including Average(), Min(), and Max() for common non-nullable numeric sequences, can throw when no values are available. Check the data or use an appropriate nullable result strategy when empty input is possible.

9. Grouping Data with GroupBy()

The GroupBy() method groups elements according to a key.

Imagine a company has employees working in different departments. You can group employees by department and process each group separately.

using System;
using System.Linq;

class Employee
{
    public string Name { get; set; } = "";
    public string Department { get; set; } = "";
}

class Program
{
    static void Main()
    {
        Employee[] employees =
        {
            new Employee { Name = "Amit", Department = "IT" },
            new Employee { Name = "Priya", Department = "HR" },
            new Employee { Name = "Rahul", Department = "IT" },
            new Employee { Name = "Neha", Department = "HR" },
            new Employee { Name = "Karan", Department = "Sales" }
        };

        var groups = employees.GroupBy(e => e.Department);

        foreach (var group in groups)
        {
            Console.WriteLine(group.Key);

            foreach (var employee in group)
            {
                Console.WriteLine($" - {employee.Name}");
            }
        }
    }
}

Output:

IT
 - Amit
 - Rahul
HR
 - Priya
 - Neha
Sales
 - Karan

group.Key represents the department used to create each group.

Grouping is useful for reports, dashboards, analytics, and summarizing records by category.

10. Removing Duplicates with Distinct()

The Distinct() method returns unique elements according to the relevant equality comparison.

using System;
using System.Linq;

class Program
{
    static void Main()
    {
        int[] numbers = { 1, 2, 2, 3, 4, 4, 5 };

        var uniqueNumbers = numbers.Distinct();

        foreach (int number in uniqueNumbers)
        {
            Console.WriteLine(number);
        }
    }
}

Output:

1
2
3
4
5

For custom classes, the definition of equality matters. If you need uniqueness by a particular property, consider an appropriate equality comparer or a grouping/projection approach.

11. Combining LINQ Methods

LINQ becomes especially useful when you combine several operations in a single query.

Consider a list of products. You want to find products costing more than ₹1,000, sort them from highest to lowest price, and display their names.

using System;
using System.Linq;

class Product
{
    public string Name { get; set; } = "";
    public decimal Price { get; set; }
}

class Program
{
    static void Main()
    {
        Product[] products =
        {
            new Product { Name = "Keyboard", Price = 1500 },
            new Product { Name = "Mouse", Price = 700 },
            new Product { Name = "Monitor", Price = 12000 },
            new Product { Name = "Headphones", Price = 2500 },
            new Product { Name = "USB Cable", Price = 300 }
        };

        var result = products
            .Where(p => p.Price > 1000)
            .OrderByDescending(p => p.Price)
            .Select(p => new
            {
                p.Name,
                p.Price
            });

        foreach (var product in result)
        {
            Console.WriteLine(
                $"{product.Name}: ₹{product.Price}");
        }
    }
}

Output:

Monitor: ₹12000
Headphones: ₹2500
Keyboard: ₹1500

This query performs three operations:

  1. Where() filters products by price.

  2. OrderByDescending() sorts the matching products.

  3. Select() projects each product into an object containing its name and price.

The operations are composed into a readable pipeline.

12. Deferred Execution and Immediate Execution

Understanding execution behavior is important when using LINQ.

Deferred Execution

Many LINQ queries over collections do not execute immediately when you define them. They execute when you enumerate the results, for example with a foreach loop.

using System;
using System.Linq;

class Program
{
    static void Main()
    {
        int[] numbers = { 1, 2, 3, 4, 5 };

        var result = numbers.Where(n => n > 3);

        numbers[3] = 40;

        foreach (int number in result)
        {
            Console.WriteLine(number);
        }
    }
}

Output:

40
5

The query is evaluated when the results are enumerated, so it sees the updated array value.

Immediate Execution

Some methods execute the query immediately and return a materialized result or a single value.

Examples include:

  • ToList()

  • ToArray()

  • Count()

  • Sum()

  • First()

For example:

var result = numbers
    .Where(n => n > 3)
    .ToList();

The query is evaluated when ToList() is called, and the matching values are stored in a new list.

Important: LINQ-to-Objects commonly uses deferred execution for filtering and projection. Other providers, such as Entity Framework Core, translate supported queries into operations against their data source, so execution behavior depends on the provider and operation.

13. LINQ with SQL Databases

LINQ can also be used with databases through frameworks such as Entity Framework Core.

For example, a database-backed application may contain a Products entity and a database context named AppDbContext.

var products = await dbContext.Products
    .Where(p => p.Price > 1000)
    .OrderByDescending(p => p.Price)
    .Select(p => new
    {
        p.Name,
        p.Price
    })
    .ToListAsync();

This example assumes that dbContext is a configured Entity Framework Core context, Products is a valid DbSet, and the containing method supports await.

Entity Framework Core translates supported LINQ operations into a database query and executes it when ToListAsync() is awaited.

Important Considerations

  • Add the appropriate Entity Framework Core package and namespace for asynchronous query extensions.

  • Prefer projecting only the fields your application needs.

  • Understand which operations your provider can translate.

  • Be mindful of query performance, indexes, and the volume of data returned.

  • Use asynchronous database operations when appropriate for application responsiveness.

LINQ syntax is similar across collections and database queries, but the execution provider determines how the query is performed.

14. Common LINQ Mistakes to Avoid

Mistake 1: Forgetting the System.Linq Namespace

For many common LINQ extension methods, you need:

using System.Linq;

Modern projects may include this namespace through global usings, but traditional projects may require the explicit statement.

Mistake 2: Using First() Without Checking Whether a Match Exists

First() throws if the sequence contains no matching element. Use FirstOrDefault() when no match is an acceptable result, and handle the default value correctly.

Mistake 3: Assuming a Query Executes Immediately

Many LINQ queries are deferred. If you need a snapshot of the results, materialize the query using ToList() or ToArray().

Mistake 4: Repeating Expensive Queries

Repeated enumeration can repeat work or database requests, depending on the query and provider. Materialize results when appropriate and avoid unnecessary repeated execution.

Mistake 5: Using LINQ for Every Operation

A simple loop may be clearer when the logic involves complex state changes, early exits, or multiple side effects. Choose the approach that makes the intent easiest to understand.

Mistake 6: Ignoring Database Query Translation

Not every .NET method can be translated by every LINQ provider. Check the provider's supported operations and inspect generated SQL when database performance matters.

15. Best Practices for Writing LINQ Queries

  • Use descriptive variable and property names.

  • Break long queries into multiple lines for readability.

  • Use Where() for filtering and Select() for projection.

  • Use Any() when you only need to determine whether a match exists.

  • Prefer FirstOrDefault() when an empty result is valid.

  • Materialize a query only when necessary.

  • Avoid unnecessary sorting, grouping, and repeated enumeration.

  • Project only required properties when querying large data sources.

  • Test edge cases, including empty collections and missing matches.

  • Consider the behavior of the underlying provider when using LINQ with a database.

16. Practice Exercises

Complete these exercises to strengthen your LINQ skills.

Exercise 1: Filter Numbers

Create a list of integers and use Where() to display numbers greater than 50.

Exercise 2: Select Names

Create a list of student names and use Select() to convert each name to uppercase.

Exercise 3: Sort Products

Create a collection of products and sort them by price in ascending and descending order.

Exercise 4: Find a Student

Use FirstOrDefault() to find a student by name. Display a suitable message if no student is found.

Exercise 5: Calculate Marks

Create a list of student marks and calculate the count, total, average, minimum, and maximum.

Exercise 6: Group Employees

Create employee records and group them by department using GroupBy().

Exercise 7: Remove Duplicates

Create a list containing repeated numbers and return unique values using Distinct().

Exercise 8: Build a Combined Query

Create a list of products, filter those priced above ₹500, sort them by price, and select only their names.

17. Quick Knowledge Check

1. What does LINQ stand for?

A. Language Integrated Query
B. Logical Internal Query
C. Linked Internet Query
D. Language Input Queue

Correct answer: A

2. Which LINQ method filters elements based on a condition?

A. Select()
B. Where()
C. OrderBy()
D. Sum()

Correct answer: B

3. Which method sorts elements in descending order?

A. OrderBy()
B. GroupBy()
C. OrderByDescending()
D. Distinct()

Correct answer: C

4. Which method removes duplicate values from a sequence?

A. Distinct()
B. Where()
C. Count()
D. First()

Correct answer: A

5. What does Select() primarily do?

A. Sorts a collection
B. Transforms or projects elements
C. Removes every duplicate
D. Deletes database records

Correct answer: B

6. Which method checks whether at least one element matches a condition?

A. Average()
B. OrderBy()
C. Any()
D. ToArray()

Correct answer: C

18. Frequently Asked Questions (FAQs)

What is LINQ in C#?

LINQ stands for Language Integrated Query. It allows developers to filter, sort, group, transform, and query data using C# syntax and methods.

What is the difference between LINQ query syntax and method syntax?

Query syntax uses keywords such as from, where, and select. Method syntax uses methods such as Where(), Select(), and OrderBy(). Both styles can express many of the same queries.

What is the difference between Where() and Select()?

Where() filters elements based on a condition. Select() transforms elements or projects selected properties into a new result.

Is LINQ used only with SQL databases?

No. LINQ can query in-memory collections, arrays, lists, XML, and supported database sources through frameworks such as Entity Framework Core.

What is deferred execution in LINQ?

Deferred execution means that a query is not evaluated until its results are enumerated or an operation requires evaluation. This behavior applies to many LINQ queries, though exact behavior depends on the provider and operation.

Is LINQ faster than a foreach loop?

Not necessarily. LINQ can make code more readable, but performance depends on the operation, implementation, provider, and data size. Benchmark performance-sensitive code rather than assuming one approach is always faster.

Why do LINQ methods require System.Linq?

Many LINQ operations are implemented as extension methods in the System.Linq namespace. Importing that namespace makes those methods available in the usual way.

Conclusion

LINQ is an essential C# feature that simplifies data querying and manipulation. With methods such as Where(), Select(), OrderBy(), GroupBy(), and Distinct(), developers can express common data operations clearly and combine them into maintainable queries.

Start by practicing LINQ with arrays and lists. Then explore grouping, aggregation, deferred execution, and database queries using Entity Framework Core.

A strong understanding of LINQ will help you write cleaner code and prepare you for building real-world .NET applications.

←
Post 24 of 30
→