Introducing LINQ for Visual Basic
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.
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 Files\LINQ 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 example 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 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
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
Using Ordering Clauses in LINQ
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 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
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
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
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
No comments:
Post a Comment