Projecting XML from LINQ to SQL by ThinqLinq

Projecting XML from LINQ to SQL

Among the new cool features in Visual Studio 2008, one of the best may be the XML Literal support with VB 9 and LINQ. In my last post, I mentioned some changing features from the Beta to RTM. One that could easily be overlooked is a change to the way LINQ to SQL can now directly project into XML literals.

Through the Beta cycle, there was an issue with projecting XML elements directly from a LINQ to SQL query. If you haven't seen LINQ to SQL with XML, here's a code sample that explains what I'm referring to:

Dim dc As New LinqBlogDataContext
'Formulate the Query to get the last 10 blog posts
Dim query = (From p In dc.PostItems _
                     
Order By p.PublicationDate Descending _
                     
Take 10 _
                      
Select p).ToArray

'Create a root Site node with 10 child "item" nodes.
'Each node will be filled in through a LINQ query
Dim fooShort = _
 
<site>
       
<%= From p In query _
                
Select _
            
<item>
                 
<title><%= p.Title %></title>
                 
<link>http://ThinqLinq.com/Default.aspx?Postid=<%= p.Id %></link>
                 
<pubDate><%= p.PublicationDate %></pubDate>
                 
<guid isPermaLink="false">42f563c8-34ea-4d01-bfe1-2047c2222a74:<%
p.Id %></guid>
                 
<description><%= p.Description %></description>
                
</item> %>
 
</site>

In this code, I'm performing two queries. The first one sets up the LINQ to SQL query and pre-fetches the results into an Array. In the beta builds, if we didn't include the pre-fetching ToArray, the second query which projects the results of the first into individual <item> nodes. What is the difference between these queries? The first query uses LINQ to SQL and projects results directly from the database. Because we pre-fetch the results into an array of objects, the resulting query only uses LINQ to Objects rather than the direct LINQ to SQL implementation.

With the final RTM of Visual Studio, we no longer need to pre-fetch the results from the query. Instead, we can directly project our desired XML from the select statement without needing the intermediary step. Here is the revised code. Notice, we can now perform the same result with a single LINQ query rather than two.

Dim fooNew = _
 
<site>
      
<%= From p In dc.PostItems _
                Order By p.PublicationDate Descending _
               
Take 10 _
                
Select _
           
<item>
               
<title><%= p.Title %></title>
               
<link>http://ThinqLinq.com/Default.aspx?Postid=<%= p.Id %></link>
               
<pubDate><%= p.PublicationDate %></pubDate>
               
<guid isPermaLink="false">42f563c8-34ea-4d01-bfe1-2047c2222a74:<%= p.Id %></guid>
               
<description><%= p.Description %></description>
           
</item> %>
   
</site>

The result is more concise. You may find you want to continue separating your query definition from your XML creation in order to improve maintainability. If this is the case, simply keep the first code sample and remove the call to .ToArray. Because LINQ to SQL is composable, you can separate the queries into two code sets. When the query is evaluated, the two expressions will be combined into a single query to the database and the projection will continue to work.

Enjoy working with VB 9 and XML. In my opinion it is one of the killer features of Visual Studio 2008. If you give it a try, I think you might find the same.

Posted on - Comment
Categories: VB - LINQ - Linq to XML -
comments powered by Disqus