LINQ (Language Integrated Query) | C#

LINQ (Language Integrated Query) 

LINQ (Language Integrated Query) allows you to write expressive queries in C# for various data sources, including collections, databases, XML, and more. 

LINQ is a set of features in C# that allows you to query data using a SQL-like syntax directly in your code. It simplifies querying and manipulating collections, databases, XML, and more.


Example of LINQ queries using a collection of `Person` objects:



using System;

using System.Collections.Generic;

using System.Linq;


public class Person

{

    public int ID { get; set; }

    public string FirstName { get; set; }

    public string LastName { get; set; }

    public int Age { get; set; }

}


public class Program

{

    public static void Main(string[] args)

    {

        // Sample collection of Person objects

        List<Person> people = new List<Person>

        {

            new Person { ID = 1, FirstName = "John", LastName = "Doe", Age = 30 },

            new Person { ID = 2, FirstName = "Jane", LastName = "Smith", Age = 25 },

            new Person { ID = 3, FirstName = "Bob", LastName = "Johnson", Age = 35 },

            new Person { ID = 4, FirstName = "Alice", LastName = "Brown", Age = 28 },

            new Person { ID = 5, FirstName = "Eve", LastName = "Davis", Age = 40 }

        };


        // LINQ Query: Retrieve all people with age greater than 30

        var query = from person in people

                    where person.Age > 30

                    select person;


        Console.WriteLine("People older than 30:");

        foreach (var person in query)

        {

            Console.WriteLine($"{person.FirstName} {person.LastName}, Age: {person.Age}");

        }


        // LINQ Method Syntax: Retrieve all people with age less than 30

        var youngerPeople = people.Where(person => person.Age < 30);


        Console.WriteLine("\nYounger people (Age < 30):");

        foreach (var person in youngerPeople)

        {

            Console.WriteLine($"{person.FirstName} {person.LastName}, Age: {person.Age}");

        }


        // LINQ OrderBy and ThenBy: Sort people by last name, then by first name

        var sortedPeople = people.OrderBy(person => person.LastName)

                                 .ThenBy(person => person.FirstName);


        Console.WriteLine("\nPeople sorted by last name, then by first name:");

        foreach (var person in sortedPeople)

        {

            Console.WriteLine($"{person.FirstName} {person.LastName}");

        }

    }

}


In this example, we have a collection of `Person` objects, and we use LINQ to perform various operations:


1. The first query retrieves people older than 30 using the query syntax.

2. The second query retrieves younger people (age < 30) using the method syntax.

3. The third query sorts people by last name and then by first name using `OrderBy` and `ThenBy`.


The `ThenBy` method in LINQ is used for secondary sorting within a collection. It allows you to further refine the order of elements after applying the initial `OrderBy` or `OrderByDescending` operation. This is useful when you want to sort elements by multiple criteria.


Here's an example using the `ThenBy` method:


Suppose you have a collection of `Person` objects with properties `LastName` and `FirstName`. You want to sort these people first by their last names in ascending order and then by their first names in ascending order:


using System;

using System.Collections.Generic;

using System.Linq;


public class Person

{

    public string FirstName { get; set; }

    public string LastName { get; set; }

}


public class Program

{

    public static void Main(string[] args)

    {

        List<Person> people = new List<Person>

        {

            new Person { FirstName = "John", LastName = "Doe" },

            new Person { FirstName = "Jane", LastName = "Smith" },

            new Person { FirstName = "Alice", LastName = "Brown" },

            new Person { FirstName = "Bob", LastName = "Johnson" }

        };


        // Sort by Last Name, then by First Name

        var sortedPeople = people.OrderBy(person => person.LastName)

                                 .ThenBy(person => person.FirstName);


        foreach (var person in sortedPeople)

        {

            Console.WriteLine($"{person.LastName}, {person.FirstName}");

        }

    }

}


In this example:


1. We first use `OrderBy` to sort the `people` collection by the `LastName` property in ascending order.

2. We then use `ThenBy` to sort the resulting sequence by the `FirstName` property in ascending order.


The output will be a list of people sorted first by last name and then, for those with the same last name, by first name:


```

Brown, Alice

Doe, John

Johnson, Bob

Smith, Jane

```


The `ThenBy` method allows you to apply secondary sorting conditions after the primary sorting condition, creating more complex sorting orders as needed.


What are the standard query operators in LINQ?

   - LINQ provides a set of standard query operators like `Where`, `Select`, `OrderBy`, `GroupBy`, `Join`, `Aggregate`, etc. Each operator serves a specific query purpose.


What is the difference between `IEnumerable` and `IQueryable` in LINQ?

   - `IEnumerable` represents an in-memory collection and performs LINQ queries locally. `IQueryable` represents a query that can be executed against a database, allowing for deferred execution and optimization of queries.


What is deferred execution in LINQ?

   - Deferred execution means that a LINQ query is not executed immediately when it's defined but is executed when the data is actually enumerated (e.g., when you iterate over the result).

Deferred execution in LINQ means that the execution of a query is delayed until the actual results are enumerated or retrieved. 


Here's a code example to illustrate deferred execution:


using System;

using System.Collections.Generic;

using System.Linq;


public class Program

{

    public static void Main(string[] args)

    {

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


        // Define a LINQ query, but it won't execute immediately

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


        // At this point, the query hasn't been executed yet


        // Enumerate the results by iterating over the query

        foreach (var number in query)

        {

            Console.WriteLine(number);

        }


        // Now, the query is executed and filtered results are printed


        // You can perform additional operations, and the query will execute when needed

        var sum = query.Sum();


        Console.WriteLine($"Sum of even numbers: {sum}");

    }

}


In this example:


1. We define a LINQ query using the `Where` method to filter even numbers from the `numbers` list. Note that the query is not executed at this point.


2. We iterate over the query using a `foreach` loop. It's at this point that the query is executed, and only even numbers are printed.


3. We perform another operation, `Sum`, on the same query. Again, the query is executed, and the sum of even numbers is calculated.


Deferred execution allows LINQ to optimize queries and avoid unnecessary work until the actual results are needed. This can be especially beneficial when working with large data sources or databases, as it helps minimize the amount of data retrieved and processed.

Comments