Master C# Programming From Scratch

Clear, interactive, and structured coding lessons designed for absolute beginners.

LINQ (Language Integrated Query)

LINQ stands for Language Integrated Query. It provides a consistent way to query and manipulate data from collections, arrays, databases, XML, and other data sources using C# syntax.

Simple Definition: LINQ allows developers to filter, sort, search, group, transform, and calculate data using readable C# queries.

What is LINQ?

Normally, developers may need to write loops and conditions repeatedly to search or filter data. LINQ provides methods and query syntax that make these operations easier to read and maintain.

LINQ can work with in-memory collections such as List, Array, and Dictionary. It is also widely used with technologies such as Entity Framework Core.

Why Use LINQ?

  • Makes data querying easier.
  • Reduces repetitive loops and conditions.
  • Improves code readability.
  • Provides filtering, sorting, grouping, and projection.
  • Works with many different data sources.
  • Works naturally with lambda expressions.

LINQ Namespace

LINQ extension methods such as Where(), Select(), OrderBy(), and GroupBy() are available through the System.Linq namespace.

C#
using System.Linq;

Basic LINQ Example

The following example filters numbers greater than 20.

C#
using System;
 
using System.Collections.Generic;
using System.Linq;

class Program
{
    static void Main()
    {
        List<int> numbers =
            new List<int> { 10, 20, 30, 40, 50 };

        var result =
            numbers.Where(number => number > 20);

        foreach (int number in result)
        {
            Console.WriteLine(number);
        }
    }
}
Output
30
40
50

Where()

Where() is used to filter elements based on a condition. It returns the elements that satisfy the specified condition.

C#
using System;
 
List<int> marks =
    new List<int> { 35, 55, 65, 40, 80 };

var passed =
    marks.Where(mark => mark >= 50);

foreach (int mark in passed)
{
    Console.WriteLine(mark);
}
Output
55
65
80

Select()

Select() is used to transform each element into another form.

C#
using System;
 
List<int> numbers =
    new List<int> { 1, 2, 3, 4, 5 };

var squares =
    numbers.Select(number => number * number);

foreach (int number in squares)
{
    Console.WriteLine(number);
}
Output
1
4
9
16
25

OrderBy()

OrderBy() sorts data in ascending order.

C#
using System;
 
List<int> numbers =
    new List<int> { 50, 20, 40, 10, 30 };

var result =
    numbers.OrderBy(number => number);

foreach (int number in result)
{
    Console.WriteLine(number);
}
Output
10
20
30
40
50

OrderByDescending()

OrderByDescending() sorts data in descending order.

C#
using System;
 
List<int> numbers =
    new List<int> { 10, 50, 20, 40, 30 };

var result =
    numbers.OrderByDescending(number => number);

foreach (int number in result)
{
    Console.WriteLine(number);
}
Output
50
40
30
20
10

First()

First() returns the first element from a sequence. If the sequence is empty, First() throws an exception.

C#
using System;
 
List<int> numbers =
    new List<int> { 10, 20, 30 };

int result = numbers.First();

Console.WriteLine(result);
Output
10

FirstOrDefault()

FirstOrDefault() returns the first element if available. Otherwise, it returns the default value of the type.

C#
using System;
 
List<int> numbers =
    new List<int>();

int result = numbers.FirstOrDefault();

Console.WriteLine(result);
Output
0

Single()

Single() expects exactly one matching element. If there are zero or multiple matching elements, it throws an exception.

C#
using System;
 
List<int> numbers =
    new List<int> { 10, 20, 30 };

int result =
    numbers.Single(number => number == 20);

Console.WriteLine(result);
Output
20

Any()

Any() checks whether at least one element satisfies a condition.

C#
using System;
 
List<int> numbers =
    new List<int> { 10, 20, 30 };

bool result =
    numbers.Any(number => number > 25);

Console.WriteLine(result);
Output
True

All()

All() checks whether every element satisfies a condition.

C#
using System;
 
List<int> marks =
    new List<int> { 60, 70, 80, 90 };

bool result =
    marks.All(mark => mark >= 50);

Console.WriteLine(result);
Output
True

Count()

Count() returns the number of elements in a collection. It can also count elements that satisfy a condition.

C#
using System;
 
List<int> numbers =
    new List<int> { 10, 20, 30, 40, 50 };

int result =
    numbers.Count(number => number > 25);

Console.WriteLine(result);
Output
3

Sum()

Sum() calculates the total of numeric values.

C#
using System;
 
List<int> numbers =
    new List<int> { 10, 20, 30 };

int total = numbers.Sum();

Console.WriteLine(total);
Output
60

Average()

Average() calculates the average value of numeric data.

C#
using System;
 
List<int> marks =
    new List<int> { 60, 70, 80 };

double average = marks.Average();

Console.WriteLine(average);
Output
70

Min() and Max()

Min() returns the smallest value and Max() returns the largest value.

C#
using System;
 
List<int> numbers =
    new List<int> { 10, 50, 20, 40, 30 };

Console.WriteLine(numbers.Min());
Console.WriteLine(numbers.Max());
Output
10
50

Skip()

Skip() ignores a specified number of elements from the beginning of a sequence.

C#
using System;
 
List<int> numbers =
    new List<int> { 10, 20, 30, 40, 50 };

var result = numbers.Skip(2);

foreach (int number in result)
{
    Console.WriteLine(number);
}
Output
30
40
50

Take()

Take() returns a specified number of elements from the beginning of a sequence.

C#
using System;
 
List<int> numbers =
    new List<int> { 10, 20, 30, 40, 50 };

var result = numbers.Take(3);

foreach (int number in result)
{
    Console.WriteLine(number);
}
Output
10
20
30

Distinct()

Distinct() removes duplicate values from a sequence.

C#
using System;
 
List<int> numbers =
    new List<int> { 10, 20, 20, 30, 30, 30 };

var result = numbers.Distinct();

foreach (int number in result)
{
    Console.WriteLine(number);
}
Output
10
20
30

GroupBy()

GroupBy() groups elements according to a specified key. It is useful when data needs to be categorized.

C#
using System;
 
class Student
{
    public string Name { get; set; }
    public string Course { get; set; }
}

List<Student> students = new List<Student>
{
    new Student { Name = "Rahul", Course = "C#" },
    new Student { Name = "Sneha", Course = "Java" },
    new Student { Name = "Amit", Course = "C#" }
};

var groups =
    students.GroupBy(student => student.Course);

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

    foreach (var student in group)
    {
        Console.WriteLine(student.Name);
    }
}
Output
C#
Rahul
Amit
Java
Sneha

LINQ Query Syntax

LINQ supports two major styles: method syntax and query syntax. Query syntax looks similar to SQL.

C#
using System;
 
List<int> numbers =
    new List<int> { 10, 20, 30, 40, 50 };

var result =
    from number in numbers
    where number > 20
    select number;

foreach (int number in result)
{
    Console.WriteLine(number);
}
Output
30
40
50

Method Syntax vs Query Syntax

Feature Method Syntax Query Syntax
Style Uses extension methods Uses from, where, select
Example Where(x => x > 20) from x in data where x > 20 select x
Common Usage Very common in modern C# Useful for SQL-like queries

Deferred Execution

Many LINQ queries are executed when the results are actually enumerated rather than immediately when the query is created. This behavior is called deferred execution.

C#
using System;
 
List<int> numbers =
    new List<int> { 10, 20, 30 };

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

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

The Where() query represents a sequence that is evaluated when it is enumerated.

ToList()

ToList() immediately materializes the query result into a List.

C#
using System;
List<int> numbers =
    new List<int> { 10, 20, 30, 40 };

List<int> result =
    numbers.Where(number => number > 20)
           .ToList();

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

LINQ with Objects

LINQ is very useful for querying lists of objects. We can filter objects based on their properties.

C#
using System;
 
class Student
{
    public string Name { get; set; }
    public int Marks { get; set; }
}

List<Student> students = new List<Student>
{
    new Student { Name = "Rahul", Marks = 80 },
    new Student { Name = "Sneha", Marks = 45 },
    new Student { Name = "Amit", Marks = 90 }
};

var result =
    students.Where(student => student.Marks >= 50);

foreach (Student student in result)
{
    Console.WriteLine(student.Name);
}
Output
Rahul
Amit

Example🌍📩

Consider an employee management system containing thousands of employee records. LINQ can be used to find employees from a specific department, filter employees based on salary, sort employees, or calculate average salary.

C#
using System;
class Employee
{
    public string Name { get; set; }
    public string Department { get; set; }
    public int Salary { get; set; }
}

List<Employee> employees = new List<Employee>
{
    new Employee
    {
        Name = "Rahul",
        Department = "IT",
        Salary = 60000
    },

    new Employee
    {
        Name = "Sneha",
        Department = "HR",
        Salary = 50000
    },

    new Employee
    {
        Name = "Amit",
        Department = "IT",
        Salary = 75000
    }
};

var result =
    employees
    .Where(employee => employee.Department == "IT")
    .OrderByDescending(employee => employee.Salary);

foreach (Employee employee in result)
{
    Console.WriteLine(
        employee.Name + " - " + employee.Salary);
}
Output
Amit - 75000
Rahul - 60000

LINQ with Entity Framework Core

LINQ is widely used with Entity Framework Core to query relational databases using strongly typed C# expressions.

C#
var employees = dbContext.Employees
    .Where(employee => employee.Department == "IT")
    .OrderBy(employee => employee.Name)
    .ToList();

In this example, the query filters employees from the IT department, sorts them by name, and materializes the result as a List.

Important LINQ Methods

Method Purpose
Where() Filters data.
Select() Transforms or projects data.
OrderBy() Sorts data ascending.
OrderByDescending() Sorts data descending.
First() Returns the first element.
FirstOrDefault() Returns the first element or default value.
Any() Checks whether any element matches.
All() Checks whether all elements match.
Count() Counts elements.
Sum() Calculates total.
Average() Calculates average.
GroupBy() Groups data.
Distinct() Removes duplicate values.
Take() Takes a specified number of elements.
Skip() Skips a specified number of elements.

LINQ Best Practices

  • Use meaningful variable and property names.
  • Keep LINQ queries readable.
  • Avoid unnecessarily complex chained queries.
  • Use ToList() when immediate materialization is required.
  • Be aware of deferred execution.
  • When using Entity Framework Core, understand which operations are translated to SQL.
  • Use projection with Select() when only specific fields are required.

Common Mistakes

  • Calling First() when the collection may be empty.
  • Using Single() when multiple records may exist.
  • Forgetting that many LINQ queries use deferred execution.
  • Creating unnecessarily complicated queries.
  • Loading more database data than required.
  • Not understanding the difference between IEnumerable and IQueryable.
CIIT Practical Point: LINQ is one of the most important concepts for modern .NET developers. It is heavily used with collections, Entity Framework Core, APIs, business logic, reporting, filtering, sorting, and data processing.

Interview Questions

1. What is LINQ?

LINQ stands for Language Integrated Query and provides a consistent way to query and manipulate data using C#.

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

Where() filters elements based on a condition, while Select() transforms or projects elements into another form.

3. What is deferred execution?

Deferred execution means that many LINQ queries are evaluated when their results are enumerated rather than when the query is initially created.

4. What is the difference between First() and FirstOrDefault()?

First() throws an exception when no element exists, while FirstOrDefault() returns the default value when no element exists.

5. What is the difference between Any() and All()?

Any() checks whether at least one element satisfies a condition, while All() checks whether every element satisfies the condition.

6. What is GroupBy()?

GroupBy() groups elements based on a specified key.

7. What is ToList() used for?

ToList() executes/materializes the sequence into a List, which is useful when an immediate in-memory collection is required.

Summary

LINQ stands for Language Integrated Query and provides a powerful way to query and manipulate data using C#.

You learned important LINQ methods such as Where(), Select(), OrderBy(), First(), Any(), All(), Count(), Sum(), Average(), GroupBy(), Take(), Skip(), and Distinct() .

You also learned the difference between method syntax and query syntax, deferred execution, and LINQ with objects and Entity Framework Core.

LINQ is an essential skill for modern C# and .NET developers because it is widely used for collection processing, database queries, APIs, and business applications.

Practice Questions

  1. Use Where() to find numbers greater than 50.
  2. Use Select() to calculate squares of numbers.
  3. Sort a collection using OrderBy().
  4. Sort a collection using OrderByDescending().
  5. Find the first element using First().
  6. Use FirstOrDefault() with an empty collection.
  7. Use Any() to check whether a number exists.
  8. Use All() to check whether all marks are passing.
  9. Calculate the total using Sum().
  10. Calculate the average using Average().
  11. Find minimum and maximum values.
  12. Remove duplicate values using Distinct().
  13. Use GroupBy() to group students by course.
  14. Write the same LINQ query using method and query syntax.
  15. Write a LINQ query to filter employees by department and sort by salary.