VB6 Collections: The Missing LINQ

VB6 Collections: The Missing LINQ

  • Comments 2

By Jonathan Aneja

 

Hi, my name’s Jonathan and I’m a Program Manager on the VB team, working mainly on LINQ features.  One of the things I love about LINQ is it’s not just limited to querying over databases and XML – you can query over any collection of Objects.  For example, let’s say I have a collection of PurchaseOrders, and I want to return the ones that meet the following criteria:

 

  1. Ordered between June 12th and June 14th
  2. Sorted by Date (ascending), then by Total (descending)

 

At this point you’d have to write code to filter out the correct POs and then apply the double-sort criteria.  With LINQ this simply becomes:

 

Dim query = From p In PurchaseOrders _

    Where p.OrderDate >= #6/12/2006# And p.OrderDate <= #6/14/2006# _

    Select p _

    Order By p.OrderDate, p.Total Descending

 

Pretty cool so far, but if you’re like me you’re thinking “What about all that old VB6 code I wrote?  Can’t I use LINQ on a VB6 Collection?”  The answer is a resounding yes, with a little help from our friend the VB Upgrade Wizard.

 

To get started, let’s say I have a function that returns a VB6 Collection of PurchaseOrders:

 

'Returns a Collection of PurchaseOrders

Private Function LoadPOs() As Collection

 

When a VB6 project is opened with VS2005, the Upgrade Wizard migrates the project to .NET; after the conversion, the old VB6 collection is converted to the Microsoft.VisualBasic.Collection type.  So now that the code’s upgraded to .NET, how do we query against it?  First we need to Import System.Query.Sequence:

 

Imports System.Query.Sequence

 

There’s still one more issue though: LINQ requires collections to implement IEnumerable(Of T), and the VB6 Collection object doesn’t.  That’s where LINQ’s OfType() extension method saves the day:

 

        'Converts the Collection to an IEnumerable(Of PurchaseOrder)

        Dim PurchaseOrders = LoadPOs().OfType(Of PurchaseOrder)()

 

        Dim query = From p In PurchaseOrders _

            Where p.OrderDate >= #6/12/2006# And p.OrderDate <= #6/14/2006# _

            Select p _

            Order By p.OrderDate, p.Total Descending

 

OfType converts the VB6 Collection to an IEnumerable(Of PurchaseOrder), and just like that we can write any query we want.  And the best part is, we didn’t have to change a single line of the code we wrote in VB6!

 

While we’re at it, let’s write a few more queries:

        Dim query2 = From p In query _

            Where p.Total > 300 _

            Select p

 

        Dim query3 = From p In PurchaseOrders _

            Where p.Item <> "Bicycle" _

            Select p _

            Order By p.Total Descending

 

Of course, now that we’re in .NET we can take advantage of the rich functionality offered in System.Collections, in which case we don’t even need to call OfType() anymore.

 

Want to try it for yourself? Download the May 2006 LINQ CTP and let us know what you think! There’s a sample VB6 project and its upgraded .NET counterpart attached. You can find more information on LINQ at http://msdn.microsoft.com/data/ref/linq/

Attachment: VB6_to_LINQ.zip
Leave a Comment
  • Please add 5 and 8 and type the answer here:
  • Post
  • I can't ever see me having all the PO's I want to query in my client-side collection at one time, due to pagination or a previous sort. Will Linq automatically requery my database?
  • The code shown here demonstrates querying client-side, however it can also be done server-side (using a DataContext).  LINQ doesn’t automatically requery the database, however implementing this is very easy.  Also you can implement pagination using the extension methods Skip() and Take, using query.Skip((n-1)*pageSize).Take(PageSize)
Page 1 of 1 (2 items)