Language-Integrated Query (LINQ)

LINQ is simply adorable.

Basically, it allows you to perform queries (almost identically to how you would have done in MySQL) in C#. Let me show you what I mean. First, you need a data source (e.g. an array). You then define your query (you'll recognize the from, where, and select keywords), and execute it. For example, printing the even numbers that appear in an array.

int[] myNumbers = new int[10];
// populate myNumbers with 10 numbers

// To create the query, we're going to use a generic "var" type variable.
var EvenQuery =
from N in myNumbers // Note the lack of semi-colons here!
where (N % 2) == 0
select N;

// When we "execute" this query, "EvenQuery" will be a list of integers
foreach (int slacker in EvenQuery)
{
Console.WriteLine("Here's an even number! {0}", slacker);
}


Now, this is adorable because the code below effectively does the same thing:

int[] myNumbers = new int[10];
// populate myNumbers with 10 numbers

foreach (int slacker in NumQuery)
{
if (slacker % 2 == 0)
{
Console.WriteLine("Here's an even number! {0}", slacker);
}
}


Its also objectively less complicated. However, I will concede that more advanced uses of LINQ provide a more elegant solution to some problems. For example, let's say my collection of numbers above isn't sorted, but I'd like the output to be printed in sorted order. You could define an intermediate Collection of some kind to store all the even numbers, sort them, then print them. Or (making one addition to the LINQ above):

int[] myNumbers = new int[10];
// populate myNumbers with 10 numbers

// To create the query, we're going to use a generic var type variable.
var SortedEvenQuery =
from N in myNumbers // Note the lack of semi-colons here!
where (N % 2) == 0
orderby N Ascending
select N;

// When we "execute" this query, "SortedEvenQuery" will be a list of integers
foreach (int slacker in SortedEvenQuery)
{
Console.WriteLine("Here's an even number in ascending order! {0}", slacker);
}


Frustratingly, the means by which we measure how many objects are contained within any of these query results is not done by accessing a Property called Count, as we have done with various other components of C# up to this point. But instead through a method called Count().

If you had a Collection of complex objects (such as Students), you could control the query results even further by using the Group keyword to create a list of lists. For example:

var GPAByYearQuery =
from student in MyClass
group student by student.Year
orderby student.GPA Ascending; // Note the missing "select N" statement from the above queries

Which would create a list of lists, separating all students by their academic year, and for each student within each academic year to be sorted (in ascending order) by their GPA. The "native" code counterpart to this would in fact be quite expansive and difficult to update overtime (if we coded academic years differently over time, or if we introduced new academic years in the future.)

To access the individual Student objects within this query result, you'll need a nested foreach loop in order to process (1) each list and (2) the contents of that list. Such as:

foreach (var GroupByYear in GPAByYearQuery)
{
Console.WriteLine("Students from the " + GroupByYear.Key + " academic year.");
foreach (Student i in GroupByYear)
{
Console.WriteLine("\t" + i.ToString());
}
}

So there are some meaningful use cases for LINQ. I just can't help but laugh at realizing there's a querying language inside a programming language. Reminds me of a once famous rapper who became a meme from an old MTV show he hosted. Or more recently, of that Christopher Nolan film about messing with people's sleep.