I haven’t got the hang of getting code into wiki, so please open up the code and follow along. It’s one of the reasons we’re temporarily making you download the source.

Yes, it’s VB. This approach relies on the text processing features of VB 9.0 XML literals.


There are a number of imports you can explore to find out more about the overall architecture if you are impatient without documentation. The most important thing to note is that there is zero dependence on the specific wrapper. You are running against the SpInputMetadata wrapper, but the template does not know this – it only knows you’re using the stored procedure model.


Inheriting from SqlServerBase provides for reuse of some key code segments. This is not required, but is convenient.


This is a Guid ID specific to this template. It allows better error management, although that’s not used in this example.


The template is responsible for establishing the name of each file it produces. This flows down as the StoredProcedureName property which can be any naming you like. The NamingFactory will later provide support for flexible name templating separate from the template.


This is where you’re template code goes. The infrastructure already created the framework, so all you need is the actual code you want output – deleting the previous stored proc and creating the new one has already been done.
In this case, there’s two calls into the SqlServerBase’s OutputRetrieve method. Once is for the main recordset, and the other occurs for each child. Thus the stored procedure returns the parent entity and each child entity.
You’ll notice a few odd looking things about this template. The <code> element indicates to VB that it’s entering an XML literal. Within the literal <%= separators offset code. The embedded expression can be a function call or a LINQ expression.

“But wait! This is XML we’re creating” I can hear you say. Here’s the beauty of XML literals that makes them a true text processing engine. The .Value method concatenates the contents of all the XML elements in depth first order. If you look at the OutputRetrieve function you’ll see it and it’s nested functions create additional XML nodes. But when the .Value executes these are concatenated into a single string, exactly the code for the stored procedure.

In this case, the output is identical to manually concatenating all the results. I believe it is essential to readability to offset the code you’re outputting from the code running the template. Thus, all the output is in code blocks.

If you’re used to CodeSmith, there’s a probably initial freak-out factor. You are not looking at the structure of your output with a few embedded things in it. You’re looking at code. But you can trace down easily to precisely the point of any problem, and have better code support to fix it. There’s also a tight set of recommended naming that’s really essential to managing the very large templates you’ll create in .NET code.

Last edited Mar 29, 2008 at 11:26 PM by KathleenDollard, version 2


No comments yet.