LINQ in C# (Language Integrated Query)

LINQ lets you query and manipulate collections (arrays, lists, DB data) in a readable and expressive way. Think of it as SQL-like queries directly in C# code.

1. Basic LINQ Query

Fetch items from a collection using a query syntax or method syntax.

using System;
using System.Linq;

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

        // Query Syntax
        var evens = from n in numbers
                    where n % 2 == 0
                    select n;

        // Method Syntax
        var odds = numbers.Where(n => n % 2 != 0);

        Console.WriteLine("Even numbers: " + string.Join(", ", evens));
        Console.WriteLine("Odd numbers: " + string.Join(", ", odds));
    }
}

2. Filtering (Where)

Where is used to filter data based on conditions.

var result = numbers.Where(n => n > 3);
// Output: 4, 5, 6

3. Projection (Select)

Select is used to transform each element into a new form.

string[] names = { "Manoj", "Ravi", "Kiran" };
var upper = names.Select(n => n.ToUpper());
// Output: MANOJ, RAVI, KIRAN

4. Ordering (OrderBy, ThenBy)

OrderBy sorts ascending, OrderByDescending sorts descending.

var sorted = numbers.OrderByDescending(n => n);
// Output: 6, 5, 4, 3, 2, 1

5. Grouping (GroupBy)

GroupBy organizes data into groups based on a key.

string[] words = { "apple", "ant", "banana", "ball" };
var groups = words.GroupBy(w => w[0]);

foreach (var g in groups)
{
    Console.WriteLine($"Words starting with {g.Key}:");
    foreach (var word in g)
        Console.WriteLine("  " + word);
}

6. Aggregation (Count, Sum, Avg)

LINQ provides aggregate functions like Count, Sum, Average, Min, Max.

Console.WriteLine(numbers.Sum()); // 21
Console.WriteLine(numbers.Average()); // 3.5
Console.WriteLine(numbers.Max()); // 6

7. Joining

Join is used to combine data from two collections based on a key.

var students = new[] {
    new { Id = 1, Name = "Manoj" },
    new { Id = 2, Name = "Ravi" }
};
var scores = new[] {
    new { Id = 1, Score = 90 },
    new { Id = 2, Score = 85 }
};

var result = from s in students
             join sc in scores on s.Id equals sc.Id
             select new { s.Name, sc.Score };

foreach (var r in result)
    Console.WriteLine($"{r.Name} scored {r.Score}");

8. Deferred Execution

LINQ queries are not executed immediately. They run only when you iterate over them.

var query = numbers.Where(n => n > 3);
// Nothing happens yet

foreach (var n in query)
    Console.WriteLine(n); // Now executes and prints 4, 5, 6

9. Immediate Execution (ToList, ToArray)

To force immediate execution, use ToList(), ToArray(), etc.

var list = numbers.Where(n => n > 3).ToList();
// Executes immediately

10. Mixed Example

A practical LINQ query combining filtering, ordering, and projection.

var names = new[] { "Ravi", "Kiran", "Manoj", "Anil" };
var result = names
                .Where(n => n.Length > 4)
                .OrderBy(n => n)
                .Select(n => n.ToUpper());

foreach (var r in result)
    Console.WriteLine(r);
// Output: KIRAN, MANOJ