Microsoft & .NETVisual BasicIntroducing LINQ for Visual Basic

Introducing LINQ for Visual Basic

Developer.com content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More.

C# 3.0 incorporates LINQ (Language INtegrated Query), a cool technology that adds dynamic queries to all kinds of objects in a familiar SQL-like style. LINQ code looks like embedded SQL statements, which I actually don’t care for because SQL has never looked pretty to me. I also do not believe that LINQ adds clarity to code. It looks terse and somewhat ambiguous. In a nutshell, LINQ is a sexy technology (as they are fond of saying in Redmond), but it is not pretty.


This article shows you how to get LINQ for Visual Basic and begin using it now. As you read, you can begin formulating your own opinion of its elegance and usefulness.


Using LINQ for VB Now


Begin by downloading and installing LINQ. This article uses the May 2006 CTP (Community Technology Preview).


[Tip: If you like bleeding-edge technologies and want to know what Microsoft is working on for future products, check out research.microsoft.com. LINQ, for example, came out of the Omega research project.]

As with all pre-release software, you download and install with some risk. In this case, LINQ will cause minor problems with IntelliSense and CodeRush. If you rely on CodeRush, Refactor, and IntelliSense, then install LINQ on a Virtual PC instance with Visual Studio 2005 on it.


Working with the LINQ CTP


Once you have downloaded and installed LINQ, you will notice a new folder named C:Program FilesLINQ Preview. This folder contains LINQ documentation, assemblies, and examples. When you run Visual Studio after installing LINQ, you will get a message indicating LINQ for C# is installed, but LINQ for VB also will be installed.


To use LINQ and create a project, pick one of the LINQ project templates as shown in Figure 1. These project templates will add the appropriate references to LINQ assemblies and any necessary import statements.

Figure 1: LINQ Project Templates


All of the samples in this article are part of a console application, and the referenced assemblies—including Microsoft.VisualBasic.LINQ, System.Data.DLinq, and System.Xml.XLinq—will be added to your project’s list of references (see Figure 2). In fact, LINQ is supported for ADO and XML too.



Figure 2: References to Essential LINQ Assemblies


[Tip: To view the references in a VB project, click the Show all files button (highlighted in blue in Figure 2) in the Solution Explorer.]

Having installed LINQ, let’s look at some of the things you can do with this technology.


Using LINQ


LINQ is a query language for .NET—VB in the examples to follows. To be useful and intuitive, I would expect LINQ to do almost everything SQL can do. Although I didn’t test its limits, LINQ proved pretty intuitive as I developed the examples. I literally guessed at them based on what I anticipated from a query language. The following sections discuss some of the queries you can write with LINQ.


Selecting Numbers from an Array


LINQ for VB looks a little like reverse polish notation for SQL. For example, you can define an array of integers and then query that array using a WHERE predicate to return a subset of integers from an unordered set. Listing 1 shows a VB subroutine that does just that with a subset of fewer than 10 integers.


Listing 1: Select Numbers from an Array of Unordered Integers Using LINQ

Sub SampleOne()
Dim numbers = {2, 1, 34, 5, 8, 13, 21, 33}

Dim lessThanTen = From num In numbers _
Where num < 10 _
Select num

For Each Dim n In lessThanTen
Console.WriteLine(n)
Next

Console.ReadLine()

End Sub


This exampe defines an array of random integers. The LINQ query (shown in bold) defines an anonymous type lessThanTen, which becomes an instance of IEnumerable. (Anonymous types are much more spectacular to C# programmers; you VB programmers are used to this type of notation.) The LINQ query From num in numbers Where num < 10 Select Num initializes lessThanTen. And, of course, most of us know by now that any IEnumerable type can be used in a For Each statement. The result from Listing 1 are the numbers 1, 2, 5, and 8 printed to the console.


Notice that numbers uses an array initializer without explicitly declaring numbers as an array (using numbers()). The variable numbers‘s type is an anonymous type whose actual type is inferred. The same is true of the anonymous variable n. (Note the unusual location of the keyword Dim in the For Each statement. This is valid .NET 3.0 code.)

Using Ordering Clauses in LINQ


Listing 2 defines an unordered array of Fibonacci numbers and uses an ORDER clause to order the array. (Google Fibonacci for a definition. You will find these numbers pretty interesting.)


Listing 2: Ordering an Array of Integers Using LINQ

Sub SampleTwo()
Dim numbers = {2, 1, 34, 5, 8, 13, 21, 3}

Dim ordered = From num In numbers _
Select num _
Order By num

For Each Dim n In ordered
Console.WriteLine(n)
Next

Console.ReadLine()

End Sub


Listing 2 is like Listing 1 but with the addition of the Order By clause. The anonymous type ordered contains the re-ordered list of integers: 1, 2, 3, 5, 8, 13, 21, 34. Adding the keyword Descending after the clause Order By num will sort the list in reverse order. This variant is shown in Listing 3.


Listing 3: Sorting in Reverse Order

Sub SampleThree()
Dim numbers = {2, 1, 34, 5, 8, 13, 21, 33}

Dim ordered = From num In numbers _
Select num _
Order By num Descending

For Each Dim n In ordered
Console.WriteLine(n)
Next

Console.ReadLine()
End Sub


Sorting Generic Lists of Custom Types


You can also apply LINQ to custom types. Suppose I define a custom type Customer (see Listing 4) and want to sort a generic list of customers.


Listing 4: A User-Defined Customer Class

Public Class Customer

Private fid As Integer
Private fname As String
Private fcity As String

Public Sub New(ByVal id As Integer, ByVal name As String, _
ByVal city As String)
fid = id
fname = name
fcity = city
End Sub

Public Overrides Function toString() As String
Dim mask As String = “{0} is in {1}”
Return String.Format(mask, fname, fcity)
End Function

Public Property ID() As Integer
Get
Return fid
End Get
Set(ByVal value As Integer)
fid = value
End Set
End Property

Public Property Name() As String
Get
Return fname
End Get
Set(ByVal value As String)
fname = value
End Set
End Property

Public Property city() As String
Get
Return fcity
End Get
Set(ByVal value As String)
fcity = value
End Set
End Property

End Class


I can define the Customer class and instantiate a List(Of T) where T is a customer using a specific field from the class Customer (see Listing 5).


Listing 5: Initializing a Generic List of Customer Objects and Sorting Based on the City Field

Sub SampleFour()

Dim customers = New List(Of Customer)
customers.Add(New Customer(1, “Kimmel Computers”, “Plattsburgh”))
customers.Add(New Customer(2, “Fred’s Frieds”, “Memphis”))
customers.Add(New Customer(3, “House of Clams”, “Detroit”))

Dim ordered = From cust In customers _
Select cust _
Order By cust.City

For Each Dim c In ordered
Console.WriteLine(c.toString())
Next

Console.ReadLine()

End Sub


Implementing IComparable


If you modify Customer by implementing Icomparable, you can tell Customer objects how to compare themselves. Implement IComparable by adding the Implements IComparable statement to the Custom class and adding the Function CompareTo. Listing 6 shows the revised Customer class, and Listing 7 shows the revised code from Listing 5 that now uses LINQ to sort based on the implementation of IComparable.


Listing 6: Implement IComparable to Compare Customer Objects by City

Public Class Customer
Implements IComparable

Private fid As Integer
Private fname As String
Private fcity As String

Public Sub New(ByVal id As Integer, ByVal name As String, _
ByVal city As String)
fid = id
fname = name
fcity = city
End Sub

Public Overrides Function toString() As String
Dim mask As String = “{0} is in {1}”
Return String.Format(mask, fname, fcity)
End Function

Public Property ID() As Integer
Get
Return fid
End Get
Set(ByVal value As Integer)
fid = value
End Set
End Property

Public Property Name() As String
Get
Return fname
End Get
Set(ByVal value As String)
fname = value
End Set
End Property

Public Property city() As String
Get
Return fcity
End Get
Set(ByVal value As String)
fcity = value
End Set
End Property

Public Function CompareTo(ByVal obj As Object) _
As Integer Implements System.IComparable.CompareTo
Return city.CompareTo(obj.City)
End Function

End Class


Listing 7: Sorting a Generic List of IComparable Customer Objects

Sub SampleFive()
Dim customers = New List(Of Customer)
customers.Add(New Customer(1, “Kimmel Computers”, “Plattsburgh”))
customers.Add(New Customer(2, “Fred’s Frieds”, “Memphis”))
customers.Add(New Customer(3, “House of Clams”, “Detroit”))

Dim ordered = From cust In customers _
Select cust _
Order By cust

For Each Dim c In ordered
Console.WriteLine(c.toString())
Next

Console.ReadLine()
End Sub


The only difference between Listing 7 and Listing 5 is that the Order By clause now specifies that you are sorting only Customer objects. The sort field is implicit as defined by the CompareTo function.


A SQL-Like Query Language


This article introduced LINQ and demonstrated how you can combine this technology with existing technologies such as interfaces and generic lists to support a SQL-like query language in your VB.NET code. Of course, LINQ (and .NET 3.5) introduce many more capabilities, including anonymous types and support for ADO.NET and XML. Go ahead and explore.


About the Author


Paul Kimmel is the VB Today columnist for www.codeguru.com and has written several books on object-oriented programming, including Visual Basic .NET Power Coding (Addison-Wesley) and UML Demystified (McGraw-Hill/Osborne). He is the president and co-founder of the Greater Lansing Area Users Group for .NET (www.glugnet.org) and a Microsoft Visual Developer MVP.


Copyright © 2006 by Paul T. Kimmel. All Rights Reserved.

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Latest Posts

Related Stories