C# LINQ Introduction

LINQ, or Language Integrated Query, provides query syntax to bridge the gap between objects and data. Whereas SQL can only be used to query data from a database, LINQ can be used to query objects, such as generic lists, XML, data sets and more.

There are two types of syntax in LINQ, query syntax and method syntax, both of which will be discussed here. It should be note that a 'using' statement for the 'System.Linq' namespace is required in order to utilise the LINQ functionality.

Query syntax more closely resembles SQL than method syntax. Like SQL it contains clauses such as 'select', 'from' and 'where', however, they aren't in the same order, with 'from' coming first and 'select' coming last.

Below is an example of LINQ query syntax, showing how it can be used to retrieve all the names in a generic list, that begin with the letter 'F'. Once the names have been retrieved from the list, a 'foreach' loop is used to display them out to the console.

// List containing names.
List<string> people = new List<string>()
{
    "Bob",
    "Fred",
    "Alan",
    "Fiona",
    "Zoe",
    "Tom",
    "Karen",
    "Samantha"
};

// LINQ query syntax.
var listQS = (from person in people
              where person.StartsWith("F")
              orderby person
              select person);

// Display information relating to people that match the criteria.
foreach (string person in listQS)
{
    Console.WriteLine(person);
}

The resulting output from the above is as follows.

Fiona
Fred

The same query on the generic list can be performed using method syntax.

// List containing names.
List<string> people = new List<string>()
{
    "Bob",
    "Fred",
    "Alan",
    "Fiona",
    "Zoe",
    "Tom",
    "Karen",
    "Samantha"
};

// LINQ method syntax.
var listMS = people.Where(p => p.StartsWith("F"))
                   .OrderBy(p => p);

// Display information relating to people that match the criteria.
foreach (string person in listMS)
{
    Console.WriteLine(person);
}

LINQ can also be used with more complex objects. The following examples, in both query and method syntax, includes a list of 'Person' objects. The 'Person' class, includes properties for id, first name, last name, title and date of birth, as well as a method for calculating the person's age. The generic list contains a number of instances of the 'Person' class. The query, in both query and method syntax, retrieves those 'Person' objects where the date of birth is between 1 January 1980 and 31 December 1989. A 'foreach' loop is then used to display the results out to the console.

class Program
{

    static void Main(string[] args)
    {

        // List containing person objects.
        List<Person> people = new List<Person>()
        {
            { new Person(1, "Bob", "Smith", "Mr", new DateTime(1980, 01, 20)) },
            { new Person(3, "Fred", "Bloggs", "Mr", new DateTime(1975, 05, 07)) },
            { new Person(4, "Alan", "White", "Mr", new DateTime(1989, 03, 20)) },
            { new Person(5, "Fiona", "Bloggs", "Mrs", new DateTime(1985, 05, 19)) },
            { new Person(6, "Zoe", "Davis", "Miss", new DateTime(1979, 07, 11)) },
            { new Person(7, "Tom", "Ingram", "Mr", new DateTime(1971, 10, 04)) },
            { new Person(8, "Karen", "Thomas", "Mrs", new DateTime(1969, 03, 08)) },
            { new Person(9, "Samantha", "Yates", "Miss", new DateTime(1995, 08, 27)) }
        };

        // Query parameters.
        DateTime dobLower = new DateTime(1980, 1, 1);
        DateTime dobUpper = new DateTime(1989, 12, 31);

        // LINQ query syntax.
        var listBetweenQS = (from person in people
                             where person.dob.Date >= dobLower.Date &&
                                   person.dob.Date <= dobUpper.Date
                             orderby person.id
                             select person);

        // Display information relating to people that match the criteria.
        foreach (Person person in listBetweenQS)
        {

            // Variable to construct person details to display.
            string personDetails = "";

            // Construct the person information for display.
            personDetails += person.id + ") ";
            personDetails += person.firstName + " " + person.lastName;
            personDetails += " - Age: " + person.CalculateAge();
            personDetails += " (" + person.dob.Day.ToString().PadLeft(2, '0') + "/";
            personDetails += person.dob.Month.ToString().PadLeft(2, '0') + "/";
            personDetails += person.dob.Year + ")";

            // Display the constructed person information.
            Console.WriteLine(personDetails);

        }

    }

}

class Person
{

    public int id;
    public string firstName;
    public string lastName;
    public string title;
    public DateTime dob;

    // Constructor.
    public Person(int pId, string pFirsName, string pLastName, string pTitle, DateTime pDob)
    {

        id = pId;
        firstName = pFirsName;
        lastName = pLastName;
        title = pTitle;
        dob = pDob;

    }

    // Method to calculate a person's age.
    public int CalculateAge()
    {

        // Get the current date.
        DateTime dateToday = DateTime.Today;

        // Calculate the age.
        int currentAge = dateToday.Year - dob.Year;

        if (dob.Month > dateToday.Month ||
            (dob.Month == dateToday.Month && dob.Day > dateToday.Day))
        {
            currentAge -= 1;
        }

        return currentAge;

    }

}

The output displayed in the console can be seen below.

1) Bob Smith - Age: 40 (20/01/1980)
4) Alan White - Age: 31 (20/03/1989)
5) Fiona Bloggs - Age: 35 (19/05/1985)

The same result can also be achieved using method syntax.

class Program
{

    static void Main(string[] args)
    {

        // List containing person objects.
        List<Person> people = new List<Person>()
        {
            { new Person(1, "Bob", "Smith", "Mr", new DateTime(1980, 01, 20)) },
            { new Person(3, "Fred", "Bloggs", "Mr", new DateTime(1975, 05, 07)) },
            { new Person(4, "Alan", "White", "Mr", new DateTime(1989, 03, 20)) },
            { new Person(5, "Fiona", "Bloggs", "Mrs", new DateTime(1985, 05, 19)) },
            { new Person(6, "Zoe", "Davis", "Miss", new DateTime(1979, 07, 11)) },
            { new Person(7, "Tom", "Ingram", "Mr", new DateTime(1971, 10, 04)) },
            { new Person(8, "Karen", "Thomas", "Mrs", new DateTime(1969, 03, 08)) },
            { new Person(9, "Samantha", "Yates", "Miss", new DateTime(1995, 08, 27)) }
        };

        // Query parameters.
        DateTime dobLower = new DateTime(1980, 1, 1);
        DateTime dobUpper = new DateTime(1989, 12, 31);

        // LINQ method syntax.
        var listBetweenMS = people.Where(p => p.dob.Date >= dobLower.Date &&
                                              p.dob.Date <= dobUpper.Date)
                                  .OrderBy(p => p.id);

        // Display information relating to people that match the criteria.
        foreach (Person person in listBetweenMS)
        {

            // Variable to construct person details to display.
            string personDetails = "";

            // Construct the person information for display.
            personDetails += person.id + ") ";
            personDetails += person.firstName + " " + person.lastName;
            personDetails += " - Age: " + person.CalculateAge();
            personDetails += " (" + person.dob.Day.ToString().PadLeft(2, '0') + "/";
            personDetails += person.dob.Month.ToString().PadLeft(2, '0') + "/";
            personDetails += person.dob.Year + ")";

            // Display the constructed person information.
            Console.WriteLine(personDetails);

        }

    }

}

class Person
{

    public int id;
    public string firstName;
    public string lastName;
    public string title;
    public DateTime dob;

    // Constructor.
    public Person(int pId, string pFirsName, string pLastName, string pTitle, DateTime pDob)
    {

        id = pId;
        firstName = pFirsName;
        lastName = pLastName;
        title = pTitle;
        dob = pDob;

    }

    // Method to calculate a person's age.
    public int CalculateAge()
    {

        // Get the current date.
        DateTime dateToday = DateTime.Today;

        // Calculate the age.
        int currentAge = dateToday.Year - dob.Year;

        if (dob.Month > dateToday.Month ||
            (dob.Month == dateToday.Month && dob.Day > dateToday.Day))
        {
            currentAge -= 1;
        }

        return currentAge;

    }

}