A First Looq at Linq

By KENT SHARKEY on 7/23/2008 3:48:30 PM

I have to admit: I've been a little slow to have a close look at Linq. I blame this on two opinions I developed on first looking at it. The first is: "Why is there yet another data access solution from Microsoft?" It seems that almost every version of a Microsoft development product since VB 2.0 has come with a new data access method: ODBC, DAO, RDO, ADO, ADO.NET and now Linq. Each time we have been told that, "this is the one, you'll be able to access all data, in all format." Each time, we are greeted with a new learning curve, new reasons to rewrite old, functional code, and some (sometimes minimal) benefits. The second reason I haven't looked that closely at Linq is the syntax: it looks much like SQL, but with the SELECT clause at the end. It struck me as a strange way to "phrase" the request for data.

What is Linq?

For those who have been avoiding (or who just haven't had the need to look at it) the .NET Framework 3.5, Linq (Language INtegrated Query) is a new standard way of querying databases, XML and objects. The goal is to provide developers with a natural way of querying in the languages they use when developing, instead of the various languages needed for each (T-SQL, XPath, XSLT, etc.). It's a bold effort, and now that I've started to dig into it, it looks like they may have created the "final" data access model. At least until the next one.

As the name indicates, Linq queries are written in the .NET language of your choice. This allows developers to stay focussed in their "native" language, and not require additional knowledge of other query models (such as T-SQL or XPath). While this seems to be a throwback to the embedded SQL of older database access tools, it is slightly different. The main difference is that -- despite a superficial similarity -- the language used to query is not SQL. Secondly, this differs from embedded SQL in that it is not tied to a specific data store. You use basically the same query syntax for databases, XML and objects with Linq. This provides more data store independence: if you initially have the data stored in XML, but switch to a database later, your code should remain the same. In theory.

What does Linq look like?

As a simple example, you can use Linq to query a collection or array (really any IEnumerable):

VB Dim names As String() = _
{"apple", "banana", "cherry", "pear", "mango"}

Dim query = From i In names _
Where i.Length > 5 _
Order By i Ascending _
Select i

For Each item As String In query
Console.WriteLine(item)
Next

C#

String[] names = { "apple", "banana", "cherry", "pear", "mango" };

var query = from i in names
where i.Length > 5
orderby i ascending
select i;

foreach (String item in query) {
Console.WriteLine(item);
}

That var keyword

Visual Basic developers seem to have an almost automatic response to seeing the var keyword for the first time: it reminds them of the Variant datatype. In VB6, the Variant datatype could be used to store any type of data. Internally, it was a composite datatype (a union for those who have programmed in C/C++): it stored a pointer to the data, and an enumeration that identifies the stored data type. The var type (an untyped Dim statement in Visual Basic), on the other hand, does not use this model. Instead, a new variable is created. In the first example above, the query variable actually looks like the following to the compiler (VB shown, but C# is comparable):

Dim query As IEnumerable(Of String) = _
names.Where(Of String) _
(New Func(Of String, Boolean)_
(AddressOf Program._Lambda$__1)) _
.OrderBy(Of String, String) _
(New Func(Of String, String) _
(AddressOf Program._Lambda$__2))_
.Select(Of String, String) _
(New Func(Of String, String) _
(AddressOf Program._Lambda$__3))

While that line looks quite messy (certainly I wouldn't want to have to write it myself), you can get an idea of what is done to create the query data. It defines an IEnumerable generic type, where the type of the generic is string. So, despite the fact that we didn't declare a datatype, we got one, and it is strongly typed: it is not an Object or Variant type. If we later tried to assign some other type of data to it, you would get an error.

Each of the clauses added in the Linq statement become methods that point to new Func calls that determine the correct data. As an example, here is the source of the first Lambda$__1 method (the Where clause):

Private Shared Function _Lambda$__1(ByVal i As String) As Boolean
Return (i.ToString.Length > 5)
End Function

As described above, Linq isn't just for collections, you can also use it to access databases. Visual Studio 2008 makes this easier by providing the Linq to SQL Classes item in the Add New Item dialog (see Figure 1).




Figure 1: Adding Linq to SQL Classes

This opens a designer, where you can select the tables you are interested in, creating a DataContext object (see Figure 2).




Figure 2: The DataContext designer

You can then use Linq to query the database:

VB
Dim db As New NorthwindDataContext
Dim query = From p In db.Products _
Order By p.UnitPrice Descending _
Take 5 _
Select p.ProductName, p.UnitPrice

Console.WriteLine("Most expensive products")
For Each item In query
Console.WriteLine("{0} ({1:c})", _
item.ProductName, item.UnitPrice)
Next

C#

NorthwindDataContext db = new NorthwindDataContext();
var query = from p in db.Products
orderby p.UnitPrice descending
select new { p.ProductName, p.UnitPrice };

Console.WriteLine("Most expensive products");
foreach (var item in query.Take(5)) {
Console.WriteLine("{0} ({1:c})",
item.ProductName, item.UnitPrice);
}

This query returns the following:

Most expensive products
Côte de Blaye ($263.50)
Thüringer Rostbratwurst ($123.79)
Mishi Kobe Niku ($97.00)
Sir Rodney's Marmalade ($81.00)
Carnarvon Tigers ($62.50)

As you might imagine, this barely scratches the surface of Linq. In future posts, I'll discuss using Linq to XML, joining multiple tables and creating your own Linq providers.

For more information

  • 101 Sample Linq queries: C# VB
    These provide a broad selection of examples of using Linq to access collections, databases and XML.
  • Linq on MSDN
    Central page of Linq information for developers
  • Hooked on Linq
    Community site focused on using Linq
Application Development
Let Apptius save you time and money by adding functionality to your existing programs.
Microsoft Outlook
Apptius offers professional development services for custom Microsoft Outlook solutions
Microsoft Outlook Logo