Language INtegrated Query

Sun, February 18, 2007, 06:16 PM under dotNET | Orcas | LINQ
The biggest announcement at the last PDC was the LINQ project. It is now the headline feature of Orcas offered to all developers from web to client to device. Given that there are no changes to the runtime engine in Orcas, you will not be surprised to learn that LINQ is based entirely on compiler magic, the introduction of some fancy new syntax and some help from Core.dll.

LINQ simplifies querying objects, data and XML by integrating query and transform operations into the programming language (currently VB9 and C#3). It introduces a concise declarative syntax that is consistent irrespective of what your underlying data source is: in memory custom objects, datasets, XML, Entities etc. LINQ is also highly extensible which means that we are already seeing LINQ to other sources (e.g. search for blinq, plinq, linq to amazon, linq to WMI and so on).

I think that most devs will make most use of the LINQ-enabled ADO.NET (LINQ to SQL, LINQ to DataSet and LINQ to Entities) and of LINQ over XML. Before you start learning about those, it is my opinion you should learn about LINQ to objects first and then build on that.

Here is an example of some LINQ syntax:
    static void Main(string[] args)
{
var results =
from p in Process.GetProcesses()
select p;
//
foreach (var o in results)
{
Console.WriteLine(o.ToString());
}
//
Console.ReadLine();
}
This will output in your console a list of all the running processes on your machine in the following format "System.Diagnostics.Process (devenv)".

We can modify the query as follows:
        from p in Process.GetProcesses()
where p.Threads.Count > 6
select p;
...which unsurprisingly will trim the list to only show processes that have more than 6 threads.

We can modify the query further like so:
        from p in Process.GetProcesses()
where p.Threads.Count > 6
orderby p.ProcessName descending
select p;
...which due to the easily readable nature of linq, you can easily tell that it orders the resulting list of processes in descending order by the ProcessName (on my machine that puts the winlogon process at the top).

How about if I just want to see a few specific properties of each process (say Name, thread count and process id) ? Easily done by changing the query as follows:
        from p in Process.GetProcesses()
where p.Threads.Count > 6
orderby p.ProcessName descending
select new {p.ProcessName, ThreadCount = p.Threads.Count, p.Id };
...which on my machine produces this screenshot.

Finally, the Visual Basic syntax for the example above follows:
  Sub Main()
Dim results = _
From p In Process.GetProcesses() _
Where p.Threads.Count > 6 _
Order By p.ProcessName Descending _
Select New With {p.ProcessName, .ThreadCount = p.Threads.Count, p.Id}
'
For Each o In results
Console.WriteLine(o.ToString())
Next
'
Console.ReadLine()
End Sub
I think you get the idea: Picture the code you would have to write today to achieve the same results! The code above is easier to write, easier to read and maintain, and much more concise. Furthermore, because of its declarative nature, the compiler can perform any optimisations that it sees fit and is not restricted to your imperative solution (this is a promising aspect and one I'll revisit in the future). The other benefit is that the syntax you see above can be used to query XML and data as hinted at the beginning of this post. Again, you’ll hear more on that in a future blog entry.

The next step is to understand how the above funny syntax really works and that is the subject of my following blog entries available right now :)