LINQ

LINQ (Language-integrated query) provides a common query syntax for dealing with objects, databases and XML. It was introduced in C# 3.0.

In this post we shall look at using LINQ to Objects. LINQ to Objects can be used with enumerable objects such as arrays, lists and strings.

There are two ways to access LINQ in C#:

  • Method syntax
  • Query syntax

The Method syntax provides a Fluent API which is particularly handy when using IntelliSense in Visual Studio. The Query syntax is more akin to SQL.

Example : Method syntax

Let’s look at an example using the method syntax:

int[] data = new int[] { 1, 2, 3, 4, 5 };
IEnumerable<int> subset = data.Where(x => x < 5);

Here, our data source is an array of integers.
With the method syntax, the query operators are implemented as extension methods to the IEnumerable interface. This means that we need to import the System.LINQ namespace.

The filter criterion is specified by a Func delegate returning a bool. It is convenient to define this using a lambda expression.

The return value is an enumerable collection of integers, which means we can use it as the data source for another query.

Example : Query syntax

The above query is implemented using query syntax as follows:

IEnumerable<int> subset2 = from x in data where x < 5 select x;

Query execution

Note that in our examples, the query isn’t actually performed at the time the LINQ statement is executed. It simply returns an object which is able to enumerate the data when we wish to do so.

Query operators

Some of the important extension methods provided by LINQ are summarised below:

  • Where() – Filter the results
  • OrderBy() – Sort the results
  • GroupBy() – Group the results
  • Count() – Count the elements

Let’s look at some examples.

Suppose we have a Student class:

class Student
{
    public int Id { get; }
    public string Name { get; }
    public int Score { get;  }

    public Student(int id, string name, int score)
    {
        Id = id;
        Name = name;
        Score = score;
    }
}

Our test dataset is as follows:

var students = new List<Student> {
    new Student(1, "Smith", 95),
    new Student(2, "Walker", 55),
    new Student(3, "Jackson", 67),
    new Student(4, "Taylor", 87)
};

Some examples queries are shown below:

// Return a list of exam scores:
var scores = students.Select(s => s.Score);

// Return a subset of students who achieved the pass mark:
var passed = students.Where(s => s.Score >= 60);

// Count the number of successful students:
int count = students.Where(s => s.Score > 60).Count();