Using Literal XML with Embedded Expressions in VB9

Introduction

I spent the week of April 13th in Redmond at the MVP Summit. If you don’t know, MVP stands for Most Valuable Professional. One usually becomes and MVP by nomination and then having acquired some unknown amount of community kudos. For instance, lots of blogging and voluntarily helping people in newsgroups might get you there eventually. So, the MVP Summit is a way for Microsoft to thank MVPs for their free contributions, continue to foster affinity with these non-Microsoft employees, and provide MVPs with an insider’s look at upcoming features. Thanks, Microsoft.

I have to tell you I was shocked! Shocked at the few very vocal Visual Basic MVPs who sounded like whiiiinnnnneeeerrrrs. (You know who you are.) The gist of it was the people don’t treat VB programmers like real programmers or at least on a par with, say, C# programmers. They were right. VB contractors make less than C# contractors in general. But, this is not Microsoft’s fault, folks. VB can be a tough, gritty language capable of solving any problem that C# can solve, but there is an underlying problem and it lives in the VB community itself.

Many VB programmers are holding onto old VB6 and the VB6 ways of doing things; consequently, there is no room for new articles, new books, or any reason to really learn anything new. So, if VB is the poor cousin, it’s our fault. Personally, I know VB is just as good a language as any out there—well, VB9 anyway. To demonstrate that, this article crams seven cool and a bit complicated—if it’s your first time seeing them—features into an 80-line sample program.

In this article, you will get a chance to explore LINQ to SQL, generic delegates, literal XML with embedded LINQ expressions, attributes, and Lambda expressions. (Did I say in 80 lines of code?) In fact, even C# can’t do literal XML, which is way cool. So, if you know a holdout in VB6 or someone doing things the same old way, feel sorry for them because these features or too cool, too fun, and promote way too much productivity to ever go back.

Previewing the Technology Usage

The basic setup here is that a lot of data exists in databases. This data is generally read from a database, converted to some form or another, changes are made, and then the data is written back to the database. Sometimes, the data is converted to something highly transmittable, such as text/XML.

In the example in Listing 1, you will see just how easy it is to initialize database entities—classes that map to a database table—with LINQ to SQL, and how with literal XML with embedded expressions can be used to transform the entities into any shape XML tree you need. The supporting cast is comprised of Lambda expressions, generic delegates, and attributes.

Listing 1: An 80-line sample program that uses a lot of cool new capabilities provided by VB9 to do some powerful stuff.

Imports System.Data.Linq
Imports System.Data.Linq.Mapping
Imports System.Xml.Linq
Module Module1

   Sub Main()

      Dim ConvertToXML As Func(Of List(Of Shipper), String) = _
         Function(shippers) (<Shippers>
            <%= From shipper In shippers _
               Select <Shipper ShipperID=<%= shipper.ShipperID %>
                  <%= shipper.CompanyName %>>
               <Phone><%= shipper.Phone %></Phone></Shipper> %>
         </Shippers>).ToString()

      Dim northwind As Northwind = New Northwind
      Console.WriteLine(ConvertToXml(northwind.Shippers.ToList()))
      Console.ReadLine()

   End Sub
End Module


Public Class Northwind
   Inherits DataContext
   Private Shared ReadOnly connectionString As String = _
      "Data Source=BUTLER;Initial Catalog= _
       Northwind;Integrated Security=True"

   Public Sub New()
      MyBase.New(connectionString)
   End Sub

   Public ReadOnly Property Shippers() As Table(Of Shipper)
      Get
         Return Me.GetTable(Of Shipper)()
      End Get
   End Property

End Class


<Table(Name:="Shippers")> _
Public Class Shipper

   Private _shipperID As Integer
   <Column(Storage:="_shipperID")> _
   Public Property ShipperID() As Integer
      Get
         Return _shipperID
      End Get
      Set(ByVal Value As Integer)
         _shipperID = Value
      End Set
   End Property

   Private _companyName As String
   <Column(Storage:="_companyName")> _
   Public Property CompanyName() As String
      Get
         Return _companyName
      End Get
      Set(ByVal Value As String)
         _companyName = Value
      End Set
   End Property

   Private _phone As String
   <Column(Storage:="_phone")> _
   Public Property Phone() As String
      Get
         Return _phone
      End Get
      Set(ByVal Value As String)
         _phone = Value
      End Set
   End Property
End Class

Can you spot the technology usage? The Shipper class is an object relational map to the Northwind Shippers table. The Table Attribute identifies the underlying table and the ColumnAttribute identifiers the related column. The Northwind class inherits from DataContext and all you need is the connection string and LINQ to SQL is able to read and write to the database with very little code.

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read