<?xml version="1.0" encoding="utf-8"?>
<feed xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xml:lang="en-us" xmlns="http://www.w3.org/2005/Atom">
  <title>Michael Maddox - Software Development</title>
  <link rel="alternate" type="text/html" href="http://www.capprime.com/software_development_weblog/" />
  <link rel="self" href="http://www.capprime.com/software_development_weblog/SyndicationService.asmx/GetAtom" />
  <icon>favicon.ico</icon>
  <updated>2010-04-17T05:42:27.8768647-04:00</updated>
  <author>
    <name>Michael Maddox</name>
  </author>
  <subtitle>Best Practices, Knowlegde Base Type Articles, General Tech Opinions, etc.</subtitle>
  <id>http://www.capprime.com/software_development_weblog/</id>
  <generator uri="http://www.dasblog.net" version="1.8.5223.2">DasBlog</generator>
  <entry>
    <title>Looking for .NET developers to mentor in Minnesota</title>
    <link rel="alternate" type="text/html" href="http://www.capprime.com/software_development_weblog/PermaLink,guid,2c305ac6-873b-4ce7-a3e2-5613e77f361c.aspx" />
    <id>http://www.capprime.com/software_development_weblog/PermaLink,guid,2c305ac6-873b-4ce7-a3e2-5613e77f361c.aspx</id>
    <published>2010-04-17T05:42:27.8768647-04:00</published>
    <updated>2010-04-17T05:42:27.8768647-04:00</updated>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
      Are you a .NET developer in the Twin Cities, Minnesota area that would be interested
      in having a mentor?  I'm looking for .NET developers to mentor.
   </p>
        <p>
      I don't really have any specific criteria in mind and I don't expect that enough people
      read my blog/twitter that I will be overwhelmed with requests.
   </p>
        <p>
      Ambition is probably the quality I'm looking for most.
   </p>
        <p>
      If you are interested, contact me via e-mail and we can work out whether it's a good
      fit.
   </p>
        <p>
      You can learn more about me here: <a href="http://www.capprime.com/About.htm">http://www.capprime.com/About.htm</a></p>
        <p>
      You can contact me through my contact page here: <a href="http://www.capprime.com/Contact.htm">http://www.capprime.com/Contact.htm</a></p>
        <p>
      I will try to come back and update this blog post if/when I no longer have time to
      mentor additional people, so consider this offer open for the foreseeable future.
   </p>
        <img width="0" height="0" src="http://www.capprime.com/software_development_weblog/aggbug.ashx?id=2c305ac6-873b-4ce7-a3e2-5613e77f361c" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Using SMO (and failing) to get the SqlDataType of a UserDefinedDataType</title>
    <link rel="alternate" type="text/html" href="http://www.capprime.com/software_development_weblog/PermaLink,guid,14f458ec-f15c-4406-aff7-6942bd9fa92f.aspx" />
    <id>http://www.capprime.com/software_development_weblog/PermaLink,guid,14f458ec-f15c-4406-aff7-6942bd9fa92f.aspx</id>
    <published>2010-03-15T08:56:31.1125-04:00</published>
    <updated>2010-03-15T08:56:31.1125-04:00</updated>
    <category term="Knowledge Base" label="Knowledge Base" scheme="dasBlog" />
    <category term="SQL Server" label="SQL Server" scheme="dasBlog" />
    <category term="Visual Studio 2008" label="Visual Studio 2008" scheme="dasBlog" />
    <category term="SQL Server 2008" label="SQL Server 2008" scheme="dasBlog" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
      Apparently SMO can't get the SqlDataType of a UserDefinedDataType.
   </p>
        <p>
          <a href="http://msdn.microsoft.com/en-us/library/ms162169.aspx">SQL Server Management
      Objects (SMO)</a> is a pretty powerful API into Microsoft SQL Server.  I've
      been pretty happy using it in various scenarios over the years.
   </p>
        <p>
      Recently, I was surprised to find out that SMO can't get the SqlDataType underlying
      a UserDefinedDataType.  This is reproducible using the Microsoft Pubs sample
      database.
   </p>
        <p>
      Attempt #1:
   </p>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">
            <p>
      string
   </p>
          </font>
        </font>
        <font color="#000000" size="2"> databaseName = </font>
        <font color="#a31515" size="2">
          <font color="#a31515" size="2">"pubs"</font>
        </font>
        <font size="2">
          <font color="#000000">;<br /></font>
        </font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">string</font>
        </font>
        <font color="#000000" size="2"> connectionString
   = System.Configuration.</font>
        <font color="#2b91af" size="2">
          <font color="#2b91af" size="2">ConfigurationManager</font>
        </font>
        <font size="2">
          <font color="#000000">.ConnectionStrings[databaseName].ToString();</font>
        </font>
        <p>
          <font color="#2b91af" size="2">
            <font color="#2b91af" size="2">SqlConnection</font>
          </font>
          <font color="#000000" size="2"> oneSqlConnection
      = </font>
          <font color="#0000ff" size="2">
            <font color="#0000ff" size="2">new</font>
          </font>
          <font color="#000000" size="2">
          </font>
          <font color="#2b91af" size="2">
            <font color="#2b91af" size="2">SqlConnection</font>
          </font>
          <font size="2">
            <font color="#000000">(connectionString);<br /></font>
          </font>
          <font color="#2b91af" size="2">
            <font color="#2b91af" size="2">ServerConnection</font>
          </font>
          <font color="#000000" size="2"> oneServerConnection
      = </font>
          <font color="#0000ff" size="2">
            <font color="#0000ff" size="2">new</font>
          </font>
          <font color="#000000" size="2">
          </font>
          <font color="#2b91af" size="2">
            <font color="#2b91af" size="2">ServerConnection</font>
          </font>
          <font size="2">
            <font color="#000000">(oneSqlConnection);<br /></font>
          </font>
          <font color="#2b91af" size="2">
            <font color="#2b91af" size="2">Server</font>
          </font>
          <font color="#000000" size="2"> oneServer
      = </font>
          <font color="#0000ff" size="2">
            <font color="#0000ff" size="2">new</font>
          </font>
          <font color="#000000" size="2">
          </font>
          <font color="#2b91af" size="2">
            <font color="#2b91af" size="2">Server</font>
          </font>
          <font size="2">
            <font color="#000000">(oneServerConnection);<br /></font>
          </font>
          <font color="#2b91af" size="2">
            <font color="#2b91af" size="2">Database</font>
          </font>
          <font color="#000000" size="2"> oneDatabase
      = </font>
          <font color="#0000ff" size="2">
            <font color="#0000ff" size="2">new</font>
          </font>
          <font color="#000000" size="2">
          </font>
          <font color="#2b91af" size="2">
            <font color="#2b91af" size="2">Database</font>
          </font>
          <font size="2">
            <font color="#000000">(oneServer,
      databaseName);<br /></font>oneDatabase.Refresh();
      </font>
        </p>
        <font color="#2b91af" size="2">
          <font color="#2b91af" size="2">
            <p>
      UserDefinedDataType
   </p>
          </font>
        </font>
        <font color="#000000" size="2"> tidUserDefinedDataType =<br />
    </font>
        <font color="#000000" size="2">   </font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">new</font>
        </font>
        <font color="#000000" size="2"> Microsoft.SqlServer.Management.Smo.</font>
        <font color="#2b91af" size="2">
          <font color="#2b91af" size="2">UserDefinedDataType</font>
        </font>
        <font color="#000000" size="2">(oneDatabase, </font>
        <font color="#a31515" size="2">
          <font color="#a31515" size="2">"tid"</font>
        </font>
        <font color="#000000" size="2">, </font>
        <font color="#a31515" size="2">
          <font color="#a31515" size="2">"dbo"</font>
        </font>
        <font size="2">
          <font color="#000000">);<br /></font>
        </font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">bool</font>
        </font>
        <font color="#000000" size="2"> initializeDidSucceed
   = tidUserDefinedDataType.Initialize(</font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">true</font>
        </font>
        <font size="2">
          <font color="#000000">);</font>
        </font>
        <p>
      In this scenario, for reasons unknown to me, initializeDidSucceed is false!
   </p>
        <p>
      Now, if we try to access tidUserDefinedDataType.SystemType which seems like the appropriate
      data item, we get this exception:
   </p>
        <p>
      Microsoft.SqlServer.Management.Smo.PropertyNotSetException: To accomplish this action,
      set property SystemType. 
      <br />
         at Microsoft.SqlServer.Management.Smo.SqlSmoObject.OnPropertyMissing(String
      propname, Boolean useDefaultValue) 
      <br />
         at Microsoft.SqlServer.Management.Smo.PropertyCollection.RetrieveProperty(Int32
      index, Boolean useDefaultOnMissingValue) 
      <br />
         at Microsoft.SqlServer.Management.Smo.PropertyCollection.GetValueWithNullReplacement(String
      propertyName, Boolean throwOnNullValue, Boolean useDefaultOnMissingValue) 
      <br />
         at Microsoft.SqlServer.Management.Smo.UserDefinedDataType.get_SystemType() 
   </p>
        <p>
          <br />
      Attempt #2:
   </p>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">
            <p>
      string
   </p>
          </font>
        </font>
        <font color="#000000" size="2"> databaseName = </font>
        <font color="#a31515" size="2">
          <font color="#a31515" size="2">"pubs"</font>
        </font>
        <font size="2">
          <font color="#000000">;<br /></font>
        </font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">string</font>
        </font>
        <font color="#000000" size="2"> connectionString
   = System.Configuration.</font>
        <font color="#2b91af" size="2">
          <font color="#2b91af" size="2">ConfigurationManager</font>
        </font>
        <font size="2">
          <font color="#000000">.ConnectionStrings[databaseName].ToString();</font>
        </font>
        <p>
          <font color="#2b91af" size="2">
            <font color="#2b91af" size="2">SqlConnection</font>
          </font>
          <font color="#000000" size="2"> oneSqlConnection
      = </font>
          <font color="#0000ff" size="2">
            <font color="#0000ff" size="2">new</font>
          </font>
          <font color="#000000" size="2">
          </font>
          <font color="#2b91af" size="2">
            <font color="#2b91af" size="2">SqlConnection</font>
          </font>
          <font size="2">
            <font color="#000000">(connectionString);<br /></font>
          </font>
          <font color="#2b91af" size="2">
            <font color="#2b91af" size="2">ServerConnection</font>
          </font>
          <font color="#000000" size="2"> oneServerConnection
      = </font>
          <font color="#0000ff" size="2">
            <font color="#0000ff" size="2">new</font>
          </font>
          <font color="#000000" size="2">
          </font>
          <font color="#2b91af" size="2">
            <font color="#2b91af" size="2">ServerConnection</font>
          </font>
          <font size="2">
            <font color="#000000">(oneSqlConnection);</font>
          </font>
        </p>
        <font color="#2b91af" size="2">
          <font color="#2b91af" size="2">
            <p>
      Server
   </p>
          </font>
        </font>
        <font color="#000000" size="2"> oneServer = </font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">new</font>
        </font>
        <font color="#000000" size="2">
        </font>
        <font color="#2b91af" size="2">
          <font color="#2b91af" size="2">Server</font>
        </font>
        <font size="2">
          <font color="#000000">(oneServerConnection);<br /></font>
        </font>
        <font color="#2b91af" size="2">
          <font color="#2b91af" size="2">Database</font>
        </font>
        <font color="#000000" size="2"> oneDatabase
   = </font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">new</font>
        </font>
        <font color="#000000" size="2">
        </font>
        <font color="#2b91af" size="2">
          <font color="#2b91af" size="2">Database</font>
        </font>
        <font size="2">
          <font color="#000000">(oneServer,
   databaseName);<br /></font>oneDatabase.Refresh();
   </font>
        <font color="#2b91af" size="2">
          <font color="#2b91af" size="2">
            <p>
      Table
   </p>
          </font>
        </font>
        <font color="#000000" size="2"> oneTable = </font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">new</font>
        </font>
        <font color="#000000" size="2">
        </font>
        <font color="#2b91af" size="2">
          <font color="#2b91af" size="2">Table</font>
        </font>
        <font color="#000000" size="2">(oneDatabase, </font>
        <font color="#a31515" size="2">
          <font color="#a31515" size="2">"titles"</font>
        </font>
        <font color="#000000" size="2">, </font>
        <font color="#a31515" size="2">
          <font color="#a31515" size="2">"dbo"</font>
        </font>
        <font size="2">
          <font color="#000000">);<br /></font>oneTable.Refresh();
   </font>
        <p>
      Now the following values are returned:
   </p>
        <p>
      oneTable.Columns[0].Name                            
      = title_id<br />
      oneTable.Columns[0].DataType.Name               =
      tid<br />
      oneTable.Columns[0].DataType.SqlDataType      = UserDefinedDataType<br />
      oneTable.Columns[0].DataType.MaximumLength  = 6
   </p>
        <p>
      So, we can successfully get the length of the underlying data type, but we can't get
      the SqlDataType.
   </p>
        <p>
          <br />
      Attempt #3:
   </p>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">
            <p>
      USE
   </p>
          </font>
        </font>
        <font size="2">
          <font color="#000000"> pubs</font>
        </font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">
            <p>
      DECLARE
   </p>
          </font>
        </font>
        <font color="#000000" size="2"> @CurrentSchemaName </font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">VARCHAR</font>
        </font>
        <font color="#808080" size="2">
          <font color="#808080" size="2">(</font>
        </font>
        <font color="#000000" size="2">128</font>
        <font color="#808080" size="2">
          <font color="#808080" size="2">)<br /></font>
        </font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">DECLARE</font>
        </font>
        <font color="#000000" size="2"> @UserDefinedDataTypeName </font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">VARCHAR</font>
        </font>
        <font color="#808080" size="2">
          <font color="#808080" size="2">(</font>
        </font>
        <font color="#000000" size="2">128</font>
        <font color="#808080" size="2">
          <font color="#808080" size="2">)
   </font>
        </font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">
            <p>
      SET
   </p>
          </font>
        </font>
        <font color="#000000" size="2"> @CurrentSchemaName </font>
        <font color="#808080" size="2">
          <font color="#808080" size="2">=</font>
        </font>
        <font color="#000000" size="2">
        </font>
        <font color="#ff0000" size="2">
          <font color="#ff0000" size="2">'dbo'<br /></font>
        </font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">SET</font>
        </font>
        <font color="#000000" size="2"> @UserDefinedDataTypeName </font>
        <font color="#808080" size="2">
          <font color="#808080" size="2">=</font>
        </font>
        <font color="#000000" size="2">
        </font>
        <font color="#ff0000" size="2">
          <font color="#ff0000" size="2">'tid'
   </font>
        </font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">
            <p>
      SELECT
   </p>
          </font>
        </font>
        <font size="2">
          <font color="#000000"> name<br /></font>
        </font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">FROM</font>
        </font>
        <font color="#000000" size="2">
        </font>
        <font color="#008000" size="2">
          <font color="#008000" size="2">sys</font>
        </font>
        <font color="#808080" size="2">
          <font color="#808080" size="2">.</font>
        </font>
        <font color="#008000" size="2">
          <font color="#008000" size="2">types<br /></font>
        </font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">WHERE</font>
        </font>
        <font color="#000000" size="2"> user_type_id </font>
        <font color="#808080" size="2">
          <font color="#808080" size="2">=<br /></font>
        </font>
        <font color="#808080" size="2">
          <font color="#808080" size="2"> 
   (<br /></font>
        </font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">  
   SELECT</font>
        </font>
        <font size="2"> system_type_id<br /></font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">  
   FROM</font>
        </font>
        <font size="2">
        </font>
        <font color="#008000" size="2">
          <font color="#008000" size="2">sys</font>
        </font>
        <font color="#808080" size="2">
          <font color="#808080" size="2">.</font>
        </font>
        <font color="#008000" size="2">
          <font color="#008000" size="2">types<br /></font>
        </font>
        <font color="#808080" size="2">
          <font color="#808080" size="2">  
     INNER</font>
        </font>
        <font size="2">
        </font>
        <font color="#808080" size="2">
          <font color="#808080" size="2">JOIN</font>
        </font>
        <font size="2">
        </font>
        <font color="#008000" size="2">
          <font color="#008000" size="2">sys</font>
        </font>
        <font color="#808080" size="2">
          <font color="#808080" size="2">.</font>
        </font>
        <font color="#008000" size="2">
          <font color="#008000" size="2">schemas<br /></font>
        </font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">      
   ON</font>
        </font>
        <font size="2">
        </font>
        <font color="#008000" size="2">
          <font color="#008000" size="2">sys</font>
        </font>
        <font color="#808080" size="2">
          <font color="#808080" size="2">.</font>
        </font>
        <font color="#008000" size="2">
          <font color="#008000" size="2">types</font>
        </font>
        <font color="#808080" size="2">
          <font color="#808080" size="2">.</font>
        </font>
        <font color="#ff00ff" size="2">
          <font color="#ff00ff" size="2">schema_id</font>
        </font>
        <font size="2">
        </font>
        <font color="#808080" size="2">
          <font color="#808080" size="2">=</font>
        </font>
        <font size="2">
        </font>
        <font color="#008000" size="2">
          <font color="#008000" size="2">sys</font>
        </font>
        <font color="#808080" size="2">
          <font color="#808080" size="2">.</font>
        </font>
        <font color="#008000" size="2">
          <font color="#008000" size="2">schemas</font>
        </font>
        <font color="#808080" size="2">
          <font color="#808080" size="2">.</font>
        </font>
        <font color="#ff00ff" size="2">
          <font color="#ff00ff" size="2">schema_id<br /></font>
        </font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">  
   WHERE</font>
        </font>
        <font size="2">
        </font>
        <font color="#008000" size="2">
          <font color="#008000" size="2">sys</font>
        </font>
        <font color="#808080" size="2">
          <font color="#808080" size="2">.</font>
        </font>
        <font color="#008000" size="2">
          <font color="#008000" size="2">schemas</font>
        </font>
        <font color="#808080" size="2">
          <font color="#808080" size="2">.</font>
        </font>
        <font size="2">name </font>
        <font color="#808080" size="2">
          <font color="#808080" size="2">=</font>
        </font>
        <font size="2"> @CurrentSchemaName<br /></font>
        <font color="#808080" size="2">
          <font color="#808080" size="2">    
   AND</font>
        </font>
        <font size="2">
        </font>
        <font color="#008000" size="2">
          <font color="#008000" size="2">sys</font>
        </font>
        <font color="#808080" size="2">
          <font color="#808080" size="2">.</font>
        </font>
        <font color="#008000" size="2">
          <font color="#008000" size="2">types</font>
        </font>
        <font color="#808080" size="2">
          <font color="#808080" size="2">.</font>
        </font>
        <font size="2">name </font>
        <font color="#808080" size="2">
          <font color="#808080" size="2">=</font>
        </font>
        <font size="2"> @UserDefinedDataTypeName<br /></font>
        <font color="#808080" size="2">
          <font color="#808080" size="2">  )
   </font>
        </font>
        <p>
      Using straight SQL, we appear to be able to get the answer we are looking for: "varchar".
   </p>
        <p>
          <br />
      I wonder why SMO is missing this capability?
   </p>
        <img width="0" height="0" src="http://www.capprime.com/software_development_weblog/aggbug.ashx?id=14f458ec-f15c-4406-aff7-6942bd9fa92f" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Options for running T4 templates from .NET code</title>
    <link rel="alternate" type="text/html" href="http://www.capprime.com/software_development_weblog/PermaLink,guid,104d9faf-5780-42ca-88e5-c04cb88f61b3.aspx" />
    <id>http://www.capprime.com/software_development_weblog/PermaLink,guid,104d9faf-5780-42ca-88e5-c04cb88f61b3.aspx</id>
    <published>2010-02-20T10:09:50.139-05:00</published>
    <updated>2010-03-07T06:44:48.01875-05:00</updated>
    <category term="Knowledge Base" label="Knowledge Base" scheme="dasBlog" />
    <category term="T4" label="T4" scheme="dasBlog" />
    <category term="Tools" label="Tools" scheme="dasBlog" />
    <category term="Visual Studio 2008" label="Visual Studio 2008" scheme="dasBlog" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <a href="http://www.hanselman.com/blog/T4TextTemplateTransformationToolkitCodeGenerationBestKeptVisualStudioSecret.aspx">T4
      Templates</a> are really nice given that the tools are included free in Visual
      Studio (the Express Editions of Visual Studio appear to have some under-documented
      limitations when it comes to T4 support).
   </p>
        <p>
      The primary way that T4 templates are processed is from within Visual Studio. 
      That works pretty well.
   </p>
        <p>
      What if you want to process a T4 template outside of Visual Studio (as part of an
      automated build process, for example)?
   </p>
        <p>
      The easiest option for running a T4 template outside of Visual Studio is through the <a href="http://msdn.microsoft.com/en-us/library/bb126245.aspx">TextTransform.exe</a> (custom
      T4 host) command line tool.
   </p>
        <p>
      The main difficulty I've encountered using the TextTransform.exe command line tool
      is error handling.
   </p>
        <p>
      Here's a sample error (written to StandardError):<br />
      --<br />
      MyT4Template.tt(0,0) : error : Running transformation: System.InvalidCastException:
      Unable to cast object of type 'Microsoft.VisualStudio.TextTemplating.CommandLine.CommandLineHost'
      to type 'System.IServiceProvider'.<br />
         at Microsoft.VisualStudio.TextTemplatingc7fe0d0277b54f7c95c25936373918ff.GeneratedTextTransformation.TransformText()<br />
      --
   </p>
        <p>
      Notice the (0,0).  That is where the line and column numbers would normally go
      for where the error occurred.  Also notice the stack trace contains no useful
      information (the error message, at least, in this case *is* useful).
   </p>
        <p>
      The other downsides of using TextTransform.exe are similar to situations where you
      are calling out to an EXE file from code as opposed to working against an API.
   </p>
        <p>
      The main positive I've encountered using the TextTransform.exe command line tool is
      if the template processes okay in Visual Studio, it will likely process okay using
      TextTransform.exe.  The above error was generated by using a template that tried
      to reference EnvDTE.DTE which works fine from within Visual Studio, but doesn’t necessarily
      make sense to do outside of Visual Studio.
   </p>
        <p>
          <br />
      As an alternative, you might attempt to use the Visual Studio T4 engine from .NET
      code like so:<br />
      --<br /><font color="#2b91af" size="2"><font color="#2b91af" size="2">ITextTemplatingEngineHost</font></font><font color="#000000" size="2"> host
      = </font><font color="#0000ff" size="2"><font color="#0000ff" size="2">new</font></font><font size="2"><font color="#000000"> Microsoft.VisualStudio.TextTemplating.VSHost.TextTemplatingService();<br /></font></font><font color="#2b91af" size="2"><font color="#2b91af" size="2">ITextTemplatingEngine</font></font><font color="#000000" size="2"> engine
      = </font><font color="#0000ff" size="2"><font color="#0000ff" size="2">new</font></font><font color="#000000" size="2"> Microsoft.VisualStudio.TextTemplating.</font><font color="#2b91af" size="2"><font color="#2b91af" size="2">Engine</font></font><font size="2"><font color="#000000">();<br /></font></font><font color="#0000ff" size="2"><font color="#0000ff" size="2">string</font></font><font size="2"><font color="#000000"> outputCode
      = engine.ProcessTemplate(inputContent, host);</font></font><br />
      --
   </p>
        <p>
      But that won't work.  You will get these compile time errors:<br />
      --<br />
      The type 'Microsoft.VisualStudio.TextTemplating.VSHost.TextTemplatingService' has
      no constructors defined<br />
      'Microsoft.VisualStudio.TextTemplating.VSHost.TextTemplatingService' is inaccessible
      due to its protection level<br />
      --
   </p>
        <p>
          <br />
      The hardest option for running a T4 template outside of Visual Studio is by implementing
      the ITextTemplatingEngineHost interface.  There is an example of how to do that
      here:
   </p>
        <p>
          <a href="http://msdn.microsoft.com/en-us/library/bb126579.aspx">Walkthrough: Creating
      a Custom Text Template Host</a>
        </p>
        <p>
      The problem with that example is that it fails for multiple distinct reasons for templates
      that run just fine in Visual Studio and from TextTransform.exe.  It doesn’t appear
      to be even close to a full featured ITextTemplatingEngineHost implementation (it’s
      quite a "teaser" of a sample, enough to show it has potential, but not enough to show
      you how far from reality you are).
   </p>
        <p>
      Mono provides an alternative implementation of the ITextTemplatingEngineHost interface
      here:
   </p>
        <p>
          <a href="http://anonsvn.mono-project.com/viewvc/trunk/monodevelop/main/src/addins/TextTemplating/Mono.TextTemplating/Mono.TextTemplating/TemplateGenerator.cs">http://anonsvn.mono-project.com/viewvc/trunk/monodevelop/main/src/addins/TextTemplating/Mono.TextTemplating/Mono.TextTemplating/TemplateGenerator.cs</a>
        </p>
        <p>
      And while that fails less often on templates that run just fine in Visual Studio,
      it still fails in multiple ways.  I appreciate what the Mono folks have done,
      but for this use case (trying to run T4 templates outside of Visual Studio), there
      isn’t much value add.
   </p>
        <p>
      The advantage of using a custom ITextTemplatingEngineHost host implementation is you
      have significantly more power and control than you have with TextTransform.exe. 
      TextTransform.exe has a limited input/output/error mechanism and its internals are
      not very extensible/customizable.
   </p>
        <p>
      The disadvantage of using a custom ITextTemplatingEngineHost host implementation (as
      opposed to TextTransform.exe) is that you possibly have to write a decent amount of
      code against an undocumented system before your T4 template that processes fine in
      Visual Studio will process equivalently from .NET code (this will depend greatly on
      the contents of your T4 template).
   </p>
        <p>
      If anyone is aware of other (free or commercial) custom implementations of the ITextTemplatingEngineHost
      interface that are usable from .NET code, please let me know!<br /></p>
        <p>
          <strong>Update March 7, 2010:</strong> Apparently this will be much easier in Visual
      Studio 2010:
   </p>
        <p>
          <a href="http://msdn.microsoft.com/en-us/library/ee844259(VS.100).aspx">Generating
      Text Files at Run Time by Using Preprocessed Text Templates</a>
        </p>
        <img width="0" height="0" src="http://www.capprime.com/software_development_weblog/aggbug.ashx?id=104d9faf-5780-42ca-88e5-c04cb88f61b3" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Using NHibernate Validator Event Based Validation</title>
    <link rel="alternate" type="text/html" href="http://www.capprime.com/software_development_weblog/PermaLink,guid,99297ab9-2919-48c5-a99a-a04893437df6.aspx" />
    <id>http://www.capprime.com/software_development_weblog/PermaLink,guid,99297ab9-2919-48c5-a99a-a04893437df6.aspx</id>
    <published>2010-01-25T09:42:45.5555-05:00</published>
    <updated>2010-01-25T09:42:45.5555-05:00</updated>
    <category term="Knowledge Base" label="Knowledge Base" scheme="dasBlog" />
    <category term="NHibernate" label="NHibernate" scheme="dasBlog" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
      The main documentation for the NHibernate Validator is here:
   </p>
        <p>
          <a href="http://nhforge.org/wikis/validator/nhibernate-validator-1-0-0-documentation.aspx">http://nhforge.org/wikis/validator/nhibernate-validator-1-0-0-documentation.aspx</a>
        </p>
        <p>
      And it alludes to the fact that you can configure the validator to be called automatically
      before Insert/Update.
   </p>
        <p>
      However, it fails to clearly communicate how to do this.
   </p>
        <p>
      The important missing piece is that "ValidatorInitializer.Initialize()" needs to be
      called before the session factory gets created.
   </p>
        <p>
      Here is some working sample code:
   </p>
        <p>
          <font color="#0000ff" size="2">
            <font color="#0000ff" size="2">string</font>
          </font>
          <font size="2">
            <font color="#000000"> connectionString
      =<br />
        </font>System.Configuration.</font>
          <font color="#2b91af" size="2">
            <font color="#2b91af" size="2">ConfigurationManager</font>
          </font>
          <font size="2">.ConnectionStrings[</font>
          <font color="#a31515" size="2">
            <font color="#a31515" size="2">"Northwind"</font>
          </font>
          <font size="2">].ToString();
      </font>
        </p>
        <p>
      NHibernate.Validator.Engine.<font color="#2b91af" size="2"><font color="#2b91af" size="2">ValidatorEngine</font></font><font size="2"> oneValidatorEngine
      =<br />
        </font><font color="#0000ff" size="2"><font color="#0000ff" size="2">new</font></font><font size="2"> NHibernate.Validator.Engine.</font><font color="#2b91af" size="2"><font color="#2b91af" size="2">ValidatorEngine</font></font><font size="2">();</font></p>
        <p>
          <font size="2">NHibernate.Validator.Cfg.</font>
          <font color="#2b91af" size="2">
            <font color="#2b91af" size="2">INHVConfiguration</font>
          </font>
          <font size="2"> oneINHVConfiguration
      =<br />
        </font>
          <font color="#0000ff" size="2">
            <font color="#0000ff" size="2">new</font>
          </font>
          <font size="2"> NHibernate.Validator.Cfg.Loquacious.</font>
          <font color="#2b91af" size="2">
            <font color="#2b91af" size="2">FluentConfiguration</font>
          </font>
          <font size="2">();<br /></font>
          <font color="#008000" size="2">
            <font color="#008000" size="2">//<font color="#008000" size="2"><font color="#008000" size="2">oneINHVConfiguration</font></font>.Properties[NHibernate.Validator.Cfg.Environment.AutoregisterListeners]
      = "true";<br /></font>
          </font>
          <font size="2">oneINHVConfiguration.Properties[NHibernate.Validator.Cfg.</font>
          <font color="#2b91af" size="2">
            <font color="#2b91af" size="2">Environment</font>
          </font>
          <font size="2">.ValidatorMode]
      = </font>
          <font color="#a31515" size="2">
            <font color="#a31515" size="2">"UseExternal"</font>
          </font>
          <font size="2">;<br />
      oneINHVConfiguration.Mappings.Add(</font>
          <font color="#0000ff" size="2">
            <font color="#0000ff" size="2">new</font>
          </font>
          <font size="2"> NHibernate.Validator.Cfg.</font>
          <font color="#2b91af" size="2">
            <font color="#2b91af" size="2">MappingConfiguration</font>
          </font>
          <font size="2">(</font>
          <font color="#a31515" size="2">
            <font color="#a31515" size="2">"YourNamespaceGoesHere"</font>
          </font>
          <font size="2">, </font>
          <font color="#0000ff" size="2">
            <font color="#0000ff" size="2">null</font>
          </font>
          <font size="2">));<br />
      oneValidatorEngine.Configure(oneINHVConfiguration);
      </font>
        </p>
        <p>
      NHibernate.Cfg.<font color="#2b91af" size="2"><font color="#2b91af" size="2">Configuration</font></font><font size="2"> nHibernateConfiguration
      = </font><font color="#0000ff" size="2"><font color="#0000ff" size="2">new</font></font><font size="2"> NHibernate.Cfg.</font><font color="#2b91af" size="2"><font color="#2b91af" size="2">Configuration</font></font><font size="2">();<br />
      nHibernateConfiguration.SetProperty(NHibernate.Cfg.</font><font color="#2b91af" size="2"><font color="#2b91af" size="2">Environment</font></font><font size="2">.ConnectionString,<br />
        </font><font size="2">connectionString);<br /></font><font size="2">nHibernateConfiguration.SetProperty(NHibernate.Cfg.</font><font color="#2b91af" size="2"><font color="#2b91af" size="2">Environment</font></font><font size="2">.Dialect,<br />
        </font><font color="#0000ff" size="2"><font color="#0000ff" size="2">typeof</font></font><font size="2">(NHibernate.Dialect.</font><font color="#2b91af" size="2"><font color="#2b91af" size="2">MsSql2005Dialect</font></font><font size="2">).AssemblyQualifiedName);<br /></font><font size="2">nHibernateConfiguration.SetProperty(NHibernate.Cfg.</font><font color="#2b91af" size="2"><font color="#2b91af" size="2">Environment</font></font><font size="2">.ProxyFactoryFactoryClass,<br />
        </font><font color="#0000ff" size="2"><font color="#0000ff" size="2">typeof</font></font><font size="2">(NHibernate.ByteCode.Castle.</font><font color="#2b91af" size="2"><font color="#2b91af" size="2">ProxyFactoryFactory</font></font><font size="2">).AssemblyQualifiedName);<br />
      nHibernateConfiguration.AddAssembly(System.Reflection.</font><font color="#2b91af" size="2"><font color="#2b91af" size="2">Assembly</font></font><font size="2">.GetCallingAssembly());</font></p>
        <p>
          <font size="2">NHibernate.Validator.Cfg.</font>
          <font color="#2b91af" size="2">
            <font color="#2b91af" size="2">ValidatorInitializer</font>
          </font>
          <font size="2">.Initialize(nHibernateConfiguration,
      oneValidatorEngine);
      </font>
        </p>
        <p>
      NHibernate.<font color="#2b91af" size="2"><font color="#2b91af" size="2">ISessionFactory</font></font><font size="2"> oneISessionFactory
      = nHibernateConfiguration.BuildSessionFactory();</font></p>
        <p>
       
   </p>
        <p>
      This code throws an NHibernate.PropertyValueException instead of an NHibernate.Exceptions.GenericADOException
      / System.Data.SqlClient.SqlException, which is what we want in this case.  Another
      exception I've seen the NHibernate Validator throw is NHibernate.Validator.Exceptions.InvalidStateException.
   </p>
        <p>
      It's much easier and more pleasant to try to recover from a validation error than
      a database error.
   </p>
        <img width="0" height="0" src="http://www.capprime.com/software_development_weblog/aggbug.ashx?id=99297ab9-2919-48c5-a99a-a04893437df6" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Castle ActiveRecord and the InPlaceConfigurationSource</title>
    <link rel="alternate" type="text/html" href="http://www.capprime.com/software_development_weblog/PermaLink,guid,2e2ba2a1-3e62-4ff3-8247-27860d8873d6.aspx" />
    <id>http://www.capprime.com/software_development_weblog/PermaLink,guid,2e2ba2a1-3e62-4ff3-8247-27860d8873d6.aspx</id>
    <published>2009-09-27T08:05:50.3725-04:00</published>
    <updated>2009-09-27T08:05:50.3725-04:00</updated>
    <category term="Knowledge Base" label="Knowledge Base" scheme="dasBlog" />
    <category term="NHibernate" label="NHibernate" scheme="dasBlog" />
    <category term="Castle ActiveRecord" label="Castle ActiveRecord" scheme="dasBlog" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
      I like to store my application's configuration in app.config or web.config (depending
      on the project type) which is pretty standard for .NET applications.  Therefore,
      I'm not a big fan of ActiveRecord's XmlConfigurationSource.
   </p>
        <p>
      That said, the InPlaceConfigurationSource is somewhat difficult to puzzle out. 
      After reading the source code, I was able to bend it to my will.
   </p>
        <p>
      In particular, I like this syntax well enough:
   </p>
        <p>
      InPlaceConfigurationSource configuration =<br />
          InPlaceConfigurationSource.Build(DatabaseType.MSSQLServer2005,
      connectionString);
   </p>
        <p>
      It lets me setup my connection string and database type and default most everything
      else.
   </p>
        <p>
      The "problem" is that I can't then do something clean and simple like this:
   </p>
        <p>
      configuration.Add("show_sql", true);
   </p>
        <p>
      Instead I have to do this:
   </p>
        <p>
      Castle.Core.Configuration.MutableConfiguration oneMutableConfiguration =<br />
        (Castle.Core.Configuration.MutableConfiguration)configuration.GetConfiguration(typeof(ActiveRecordBase));<br />
      oneMutableConfiguration.Children.Add(new<br />
        Castle.Core.Configuration.MutableConfiguration("show_sql", true.ToString()));<br />
      configuration.Add(typeof(ActiveRecordBase), oneMutableConfiguration);
   </p>
        <p>
      Which works, but it's not the friendliest API to program against.
   </p>
        <p>
      Be careful, the "Add" method on InPlaceConfigurationSource is not really "Add". 
      It is really "Replace".
   </p>
        <p>
      The other main alternative for using InPlaceConfigurationSource is something like
      this, which is useful for when I can't just use the defaults:
   </p>
        <p>
      IDictionary&lt;string, string&gt; properties =<br />
        new System.Collections.Generic.Dictionary&lt;string, string&gt;();<br />
      properties.Add("connection.driver_class", "NHibernate.Driver.SqlClientDriver");<br />
      properties.Add("connection.provider",<br />
        "NHibernate.Connection.DriverConnectionProvider");<br />
      properties.Add("proxyfactory.factory_class",<br />
        "NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle");
   </p>
        <p>
      properties.Add("dialect", "NHibernate.Dialect.MsSql2005Dialect");<br />
      properties.Add("connection.connection_string", connectionString);
   </p>
        <p>
      properties.Add("show_sql", true.ToString());
   </p>
        <p>
      InPlaceConfigurationSource configuration = new InPlaceConfigurationSource();<br />
      configuration.Add(typeof(ActiveRecordBase), (IDictionary&lt;string, string&gt;)properties);
   </p>
        <p>
          <br />
      This was written and tested against "ActiveRecord 2.0 - August 1st, 2009".
   </p>
        <img width="0" height="0" src="http://www.capprime.com/software_development_weblog/aggbug.ashx?id=2e2ba2a1-3e62-4ff3-8247-27860d8873d6" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Using Linq with NHibernate : A Quick Start</title>
    <link rel="alternate" type="text/html" href="http://www.capprime.com/software_development_weblog/PermaLink,guid,162facaa-a3b9-4dc5-b770-657e27e887ad.aspx" />
    <id>http://www.capprime.com/software_development_weblog/PermaLink,guid,162facaa-a3b9-4dc5-b770-657e27e887ad.aspx</id>
    <published>2009-09-24T04:53:46.21625-04:00</published>
    <updated>2009-09-24T04:53:46.21625-04:00</updated>
    <category term="Knowledge Base" label="Knowledge Base" scheme="dasBlog" />
    <category term="LinqToSql" label="LinqToSql" scheme="dasBlog" />
    <category term="NHibernate" label="NHibernate" scheme="dasBlog" />
    <category term="SQL Server" label="SQL Server" scheme="dasBlog" />
    <category term="Visual Studio 2008" label="Visual Studio 2008" scheme="dasBlog" />
    <category term=".NET 3.5" label=".NET 3.5" scheme="dasBlog" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
      NHibernate is a great ORM.  It's mature.  It's feature rich.  It's
      free.  Source code is available if necessary.
   </p>
        <p>
      It now also supports Linq and Linq is great!
   </p>
        <p>
      This is a quick guide to getting up and running with NHibernate and Linq quickly. 
      The overall experience feels vaguely similar to LinqToSql, without all the <a href="http://www.capprime.com/software_development_weblog/PermaLink,guid,78e9dd46-b743-4d10-a541-2593354028ba.aspx">drawbacks</a> and
      lock-in of LinqToSql.
   </p>
        <p>
      We are going to assume our database already exists.  We are going to assume that
      database is Northwind, and we are going to assume that we are doing database driven
      design (as opposed to domain driven design).  Northwind setup is described below.
   </p>
        <p>
      We are going to use Visual Studio 2008 with Service Pack 1 and SQL Server 2008 Express. 
      (Note: I'm not sure if everything here will work with Visual Web Developer 2008 Express
      Edition (a completely free stack).  I have Visual Web Developer 2008 Express
      Edition installed, but I'm not sure if the Active Writer install will work with it
      since the file type isn't showing up for me.)
   </p>
        <p>
      To speed the process along, we are going to use <a href="http://www.castleproject.org/activerecord/index.html">Castle
      Active Record</a> to implement a basic <a href="http://en.wikipedia.org/wiki/Active_record_pattern">Active
      Record pattern</a>.
   </p>
        <p>
      This means we won't be using NHibernate's famous XML mapping files.
   </p>
        <p>
      And to really speed things along, we are going to use <a href="http://using.castleproject.org/display/Contrib/ActiveWriter">Castle
      ActiveWriter</a> to get some basic Active Record code generation.
   </p>
        <p>
      While I wouldn't necessarily use this stack for a production application, it's a very
      quick way to get up and running.  This example is built on NHibernate and so
      all that goodness is still available later when necessary.  You aren't really
      tied to any proprietary or inflexible features.
   </p>
        <p>
          <br />
      Step 1:
   </p>
        <p>
      Download and install ActiveWriter on top of VS 2008.  The download link is available
      from here:
   </p>
        <p>
          <a href="http://using.castleproject.org/display/Contrib/ActiveWriter">http://using.castleproject.org/display/Contrib/ActiveWriter</a>
        </p>
        <p>
      At the time of writing, the current version is "Preview 4.1 (26/06/2008)".
   </p>
        <p>
      I rebooted after the install since I have been burned one too many times, but rebooting
      is possibly not necessary.
   </p>
        <p>
          <br />
      Step 2:
   </p>
        <p>
      Next, we will download and install the Northwind database.
   </p>
        <p>
      Jeff Atwood provides approximate instructions here (ask specific questions in the
      comments if you get stuck):
   </p>
        <p>
          <a href="http://www.codinghorror.com/blog/archives/000434.html">http://www.codinghorror.com/blog/archives/000434.html</a>
        </p>
        <p>
      Follow the path for installing the binary files from the command line.  I have
      tested that the SQL 2005 instructions work on SQL 2008.
   </p>
        <p>
          <br />
      Step 3:
   </p>
        <p>
      Download Castle Active Record:
   </p>
        <p>
          <a href="http://www.castleproject.org/castle/download.html">http://www.castleproject.org/castle/download.html</a>
        </p>
        <p>
      At the time of writing, the current version is "ActiveRecord 2.0 - August 1st, 2009". 
      Unzip it and remember where you put it, you'll need that info in the next step.
   </p>
        <p>
          <br />
      Step 4:
   </p>
        <p>
      Start Visual Studio 2008
   </p>
        <p>
      We will create a new console application project:
   </p>
        <p>
      File -&gt; New -&gt; Project<br />
       Visual C# -&gt; Windows -&gt; Console Application<br />
        ConsoleApplication1 -&gt; OK
   </p>
        <p>
      We need to add the appropriate NHibernate &amp; Castle Active Record references:
   </p>
        <p>
      Solution Explorer<br />
       Right Click ConsoleApplication1 -&gt; References -&gt; Add<br />
        Browse Tab<br />
         Go to your Castle ActiveRecord 2.0 download location and add:<br />
          Castle.ActiveRecord.dll<br />
          Castle.DynamicProxy2.dll<br />
          NHibernate.dll<br />
          NHibernate.Linq.dll<br />
         Click OK
   </p>
        <p>
      And add a reference to System.Configuration as well:
   </p>
        <p>
      Solution Explorer<br />
       Right Click ConsoleApplication1 -&gt; References -&gt; Add<br />
        .NET Tab<br />
         System.Configuration<br />
        Click OK
   </p>
        <p>
          <br />
      Step 5:
   </p>
        <p>
      We will add the ActiveWriter1.actiw files to the project:
   </p>
        <p>
      Solution Explorer<br />
       Right Click ConsoleApplication1 -&gt; Add -&gt; New Item...<br />
        Visual C# Items -&gt; ActiveWriter (it's at the bottom of the list for
      me)<br />
        Add
   </p>
        <p>
      Click OK on the Security Warning
   </p>
        <p>
      Close the class details window
   </p>
        <p>
          <br />
      Step 6:
   </p>
        <p>
      We will find the Northwind database in the Server Explorer:
   </p>
        <p>
      View -&gt; Server Explorer<br />
       Data Connections -&gt; Add Connection...<br />
        Choose your Server name<br />
        Choose the correct login info<br />
        Select "Northwind" as the database<br />
        Click "Test Connection"<br />
        Assuming that succeeds, click OK<br />
       Expand the Northwind Tables node<br />
       Now drag and drop the following tables to the Active Writer Designer surface:<br />
        Orders<br />
        Shippers
   </p>
        <p>
      Save the ActiveWriter1.actiw file<br />
      Click OK on the Security Warning<br />
      Close the ActiveWriter1.actiw file
   </p>
        <p>
      You can look through the new ActiveWriter1.cs file in Solution Explorer to see the
      generated classes we are going to use later.
   </p>
        <p>
          <br />
      Step 7:
   </p>
        <p>
      We will now add an Application Configuration File to the project and put the Northwind
      Connection String into it:
   </p>
        <p>
      Solution Explorer<br />
       Right Click ConsoleApplication1 -&gt; Add -&gt; New Item...<br />
        Visual C# Items -&gt; General -&gt; Application Configuration File<br />
        Add
   </p>
        <p>
      Modify the file to look like this and use your specific DB connection info:
   </p>
        <p>
      --<br />
      &lt;?xml version="1.0" encoding="utf-8" ?&gt;<br />
      &lt;configuration&gt;<br />
        &lt;connectionStrings&gt;<br />
          &lt;add name="Northwind" connectionString="Data Source=ServerName;Initial
      Catalog=Northwind;User ID=sa;Password=password;"/&gt;<br />
        &lt;/connectionStrings&gt;<br />
      &lt;/configuration&gt;<br />
      --
   </p>
        <p>
          <br />
      Step 8:
   </p>
        <p>
      Open the main "Program.cs" class and add the following new methods:
   </p>
        <p>
              private static void InitializeNHibernateActiveRecord()<br />
              {<br />
                  string connectionString
      = System.Configuration.ConfigurationManager.ConnectionStrings["Northwind"].ToString();<br />
                  InPlaceConfigurationSource
      configuration = InPlaceConfigurationSource.Build(DatabaseType.MSSQLServer2005, connectionString);
   </p>
        <p>
                  ActiveRecordStarter.Initialize(configuration,<br />
                     
      typeof(Orders),<br />
                     
      typeof(Shippers)<br />
                     
      );<br />
              }
   </p>
        <p>
              private static ISession CreateNHibernateActiveRecordSession()<br />
              {<br />
                  // This uses the
      values setup during ActiveRecordStarter.Initialize() to configure and create the session<br />
                  return ActiveRecordMediator.GetSessionFactoryHolder().CreateSession(typeof(ActiveRecordBase));<br />
              }
   </p>
        <p>
      Add the following code to the Main Method:
   </p>
        <p>
              static void Main(string[] args)<br />
              {<br />
                  try<br />
                  {<br />
                     
      InitializeNHibernateActiveRecord();
   </p>
        <p>
                     
      using (ISession dbSession = CreateNHibernateActiveRecordSession())<br />
                     
      {<br />
                         
      var queryToExecute = from oneShippers in dbSession.Linq&lt;Shippers&gt;()<br />
                                              
      select oneShippers;
   </p>
        <p>
                         
      foreach (Shippers oneShipper in queryToExecute.ToList())<br />
                         
      {<br />
                             
      Console.WriteLine("oneShipper ShipperID=[" + oneShipper.ShipperID + "] CompanyName=["
      + oneShipper.CompanyName + "]");<br />
                         
      }               
      }<br />
                  }<br />
                  catch (Exception
      oneException)<br />
                  {<br />
                     
      Console.WriteLine("oneException=[" + oneException + "]");<br />
                     
      throw; // you can remove this if you'd rather the program exit "more normally"<br />
                  }<br />
              }
   </p>
        <p>
      Add the following using statements at the top of Program.cs:
   </p>
        <p>
      using Castle.ActiveRecord;<br />
      using Castle.ActiveRecord.Framework.Config;
   </p>
        <p>
      using NHibernate;<br />
      using NHibernate.Linq;
   </p>
        <p>
          <br />
      Step 9:
   </p>
        <p>
      Copy the NHibernate.ByteCode.Castle.dll file from your Castle Active Record download
      unzip directory to your projects bin\Debug\ folder.
   </p>
        <p>
          <br />
      Step 10:
   </p>
        <p>
      Run the application:
   </p>
        <p>
      Ctrl-F5 (Debug -&gt; Start Without Debugging)
   </p>
        <p>
      And you should see the following output:
   </p>
        <p>
      --<br />
      oneShipper ShipperID=[1] CompanyName=[Speedy Express]<br />
      oneShipper ShipperID=[2] CompanyName=[United Package]<br />
      oneShipper ShipperID=[3] CompanyName=[Federal Shipping]<br />
      Press any key to continue . . .<br />
      --
   </p>
        <p>
      So, the basics are working.
   </p>
        <p>
      I would have loved to show some Order Details instead of Shippers, but there appear
      to be a lot of complexities with the Northwind database that don't seem to work well
      with the current release versions of ActiveWriter / ActiveRecord.  Hopefully
      those issues will be fixed over time.
   </p>
        <p>
          <br />
      Step 11:
   </p>
        <p>
      Now let's do a query which requires a join.
   </p>
        <p>
      The CustomerID field on the Orders class first needs to have it's column type changed
      for it to work.
   </p>
        <p>
      (Re)open the ActiveWriter1.actiw file.
   </p>
        <p>
      Right Click on Orders -&gt; CustomerID -&gt; Properties<br />
       Set the Column Type to String
   </p>
        <p>
          <br />
      Step 12:
   </p>
        <p>
      Let's model the relationship between Orders and Shippers in the Designer.
   </p>
        <p>
      The foreign key relationship is Orders.ShipVia &lt;-&gt; Shippers.ShipperID, with
      one shipper having 0 to many orders.
   </p>
        <p>
      With the ActiveWriter1.actiw designer open, go to the toolbox (View -&gt; Toolbox).
   </p>
        <p>
      Select the "Many To One Relationship" option under "ActiveWriter".
   </p>
        <p>
      Click (and hold the click) on the Orders table and drag the line onto the Shippers
      table.
   </p>
        <p>
      Highlight the line between the two tables and right click -&gt; Properties.
   </p>
        <p>
      Set the Source Column to ShipVia<br />
      Set the Target Table to Orders
   </p>
        <p>
          <br />
      Step 13:
   </p>
        <p>
      Let's add a Linq query to the Main method for Orders to exercise that new relationship:
   </p>
        <p>
                         
      var queryToExecute = from oneOrders in dbSession.Linq&lt;Orders&gt;()<br />
                                              
      select oneOrders;
   </p>
        <p>
                         
      foreach (Orders oneOrder in queryToExecute.ToList())<br />
                         
      {<br />
                             
      Console.WriteLine("oneOrder OrderID=[" + oneOrder.OrderID + "] ShipVia=[" + oneOrder.ShipVia
      + "] Shippers.CompanyName=[" + oneOrder.Shippers.CompanyName + "]");<br />
                         
      }
   </p>
        <p>
          <br />
      Step 14:
   </p>
        <p>
      Run the application:
   </p>
        <p>
      Ctrl-F5 (Debug -&gt; Start Without Debugging)
   </p>
        <p>
      And you should see the following output:
   </p>
        <p>
      --<br />
      oneOrder OrderID=[10248] ShipVia=[3] Shippers.CompanyName=[Federal Shipping]<br />
      oneOrder OrderID=[10249] ShipVia=[1] Shippers.CompanyName=[Speedy Express]
   </p>
        <p>
      &lt;snip&gt;
   </p>
        <p>
      oneOrder OrderID=[11076] ShipVia=[2] Shippers.CompanyName=[United Package]<br />
      oneOrder OrderID=[11077] ShipVia=[2] Shippers.CompanyName=[United Package]<br />
      --
   </p>
        <p>
          <br />
      We have successfully executed a join query through Linq.
   </p>
        <p>
      I was somewhat surprised when I found out this was running 4 queries under the covers. 
      Basically:
   </p>
        <p>
      SELECT Orders.*, Shippers.* FROM Orders LEFT OUTER JOIN Shippers ON Orders.ShipVia
      = Shippers.ShipperID<br />
      SELECT * FROM Orders WHERE ShipVia = 2<br />
      SELECT * FROM Orders WHERE ShipVia = 1<br />
      SELECT * FROM Orders WHERE ShipVia = 3
   </p>
        <p>
      I either expected 1 query (eager fetch) or 831 queries (lazy fetch - 1 query for the
      list of orders + 1 query for each order to get the Shipper Company Name).
   </p>
        <p>
      The results of first query contain enough information to display what the code is
      asking for, so it's definitely eager fetch behavior.
   </p>
        <p>
      Changing the code to only print OrderID does not appear to change which queries are
      run.
   </p>
        <p>
      So don't necessarily make assumptions about how your ORM is going to be generating
      queries under the covers, especially if performance seems to be an issue when it shouldn't
      be.
   </p>
        <p>
          <br />
      Some additional things to note:
   </p>
        <p>
      Castle ActiveRecord provides an ActiveRecordLinq.AsQueryable method that would appear
      to be useable in place of the ISession.Linq method (with a call to new up a SessionScope
      instead of calling CreateSession), but I couldn't get that to work (I didn't dig into
      it).
   </p>
        <p>
      While the code sample above makes for a decent demo and a quick start, your mileage
      will likely vary.  When things work great, they work great.  This sample
      didn't end up being as I planned though because I had to work around / avoid things
      that I couldn't easily get to work (like Order Details).  In the end, I am very
      satisfied that the code sample is pretty short and straight-forward, yet so much power
      is happening behind the scenes.
   </p>
        <p>
      NHibernate supports pretty much all the weirdness your database needs, but ActiveRecord
      supports less weirdness, and ActiveWriter supports even less.  The higher up
      the stack/abstraction you get, the more likely edge cases haven't been tested/implemented
      yet.
   </p>
        <p>
      Now that you have the basic NHibernate Linq infrastructure in place, there are plenty
      of Linq examples and sample code available elsewhere.
   </p>
        <p>
      Enjoy!
   </p>
        <img width="0" height="0" src="http://www.capprime.com/software_development_weblog/aggbug.ashx?id=162facaa-a3b9-4dc5-b770-657e27e887ad" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Fun with recursion bugs</title>
    <link rel="alternate" type="text/html" href="http://www.capprime.com/software_development_weblog/PermaLink,guid,0d6e70a4-a46e-45fb-b370-325539c1efbc.aspx" />
    <id>http://www.capprime.com/software_development_weblog/PermaLink,guid,0d6e70a4-a46e-45fb-b370-325539c1efbc.aspx</id>
    <published>2009-09-07T05:22:02.243625-04:00</published>
    <updated>2009-09-07T05:22:02.243625-04:00</updated>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
      I'm sure it's been done before and I'm sure it will be done again.  Sometimes
      habits work to your advantage and sometimes they don't.
   </p>
        <p>
      Here's a case where a habit bit me recently.
   </p>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">
            <p>
      static
   </p>
          </font>
        </font>
        <font color="#000000" size="2">
        </font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">void</font>
        </font>
        <font color="#000000" size="2"> Main(</font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">string</font>
        </font>
        <font size="2">
          <font color="#000000">[]
   args)<br /></font>{<br /></font>
        <font size="2">
          <font color="#0000ff" size="2">    try<br /></font>
        </font>
        <font size="2">
          <font color="#0000ff">    </font>{<br /></font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">       
   object</font>
        </font>
        <font size="2"> dbConnection = GetDbConnectionWithRetry(0);<br /><font color="#0000ff">    </font>}<br /></font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">   
   catch</font>
        </font>
        <font size="2"> (Exception oneException)<br /><font color="#0000ff">    </font>{<br /><font color="#0000ff">        </font>Console.WriteLine("oneException=["
   + oneException.ToString() + "]");<br /><font color="#0000ff">    </font>}<br />
   }<br /></font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">
            <br />
   private</font>
        </font>
        <font color="#000000" size="2">
        </font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">static</font>
        </font>
        <font color="#000000" size="2">
        </font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">object</font>
        </font>
        <font color="#000000" size="2"> GetDbConnectionWithRetry(</font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">int</font>
        </font>
        <font size="2">
          <font color="#000000"> recursionCount)<br /></font>{<br /><font color="#0000ff">    </font>Console.WriteLine("GetDbConnectionWithRetry
   recursionCount=[" + recursionCount + "]");<br /></font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">   
   object</font>
        </font>
        <font size="2"> dbConnection = </font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">null</font>
        </font>
        <font size="2">;<br /></font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">   
   if</font>
        </font>
        <font size="2"> (recursionCount &lt; 10)<br /><font color="#0000ff">    </font>{<br /><font color="#0000ff">        </font>dbConnection
   = OpenDbConnection();<br /></font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">       
   if</font>
        </font>
        <font size="2"> (dbConnection == </font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">null</font>
        </font>
        <font size="2">)<br /><font color="#0000ff">        </font>{<br /><font color="#0000ff">            </font>dbConnection
   = GetDbConnectionWithRetry(recursionCount++);<br /><font color="#0000ff">        </font>}<br /><font color="#0000ff">    </font>}<br /></font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">   
   return</font>
        </font>
        <font size="2"> dbConnection;<br />
   }<br /></font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">
            <br />
   private</font>
        </font>
        <font color="#000000" size="2">
        </font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">static</font>
        </font>
        <font color="#000000" size="2">
        </font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">object</font>
        </font>
        <font size="2">
          <font color="#000000"> OpenDbConnection()<br /></font>{<br /></font>
        <font color="#008000" size="2">
          <font color="#008000" size="2">
            <font color="#0000ff">    </font>//
   This is just a dummy method for sample code purposes<br /></font>
        </font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">   
   return</font>
        </font>
        <font size="2">
        </font>
        <font color="#0000ff" size="2">
          <font color="#0000ff" size="2">null</font>
        </font>
        <font size="2">;<br />
   }<br /></font>
        <br />
   It's humorous in retrospect.  Can you spot the bug?  What habit should I
   break myself of?<br /><img width="0" height="0" src="http://www.capprime.com/software_development_weblog/aggbug.ashx?id=0d6e70a4-a46e-45fb-b370-325539c1efbc" /></div>
    </content>
  </entry>
  <entry>
    <title>Why I'm Using Stack Overflow</title>
    <link rel="alternate" type="text/html" href="http://www.capprime.com/software_development_weblog/PermaLink,guid,45ec5ae4-34b1-4dc3-978e-1d8cbc964a36.aspx" />
    <id>http://www.capprime.com/software_development_weblog/PermaLink,guid,45ec5ae4-34b1-4dc3-978e-1d8cbc964a36.aspx</id>
    <published>2009-08-22T08:59:00.978-04:00</published>
    <updated>2009-08-22T08:59:00.978-04:00</updated>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
      Quite a while ago, I had a fairly bad experience at Stack Overflow and wrote a blog
      post about it:
   </p>
        <p>
          <a href="http://www.capprime.com/software_development_weblog/PermaLink,guid,f9baa23d-68c1-4135-8466-d0b535a27795.aspx">StackOverflow
      Impressions - Too Many Rough Edges</a>
        </p>
        <p>
      I have now returned to being a contributor at Stack Overflow.  But why?
   </p>
        <p>
      More and more Google searches are leading me to Stack Overflow for answers. 
      The answers are often useful.  Stack Overflow has no meaningful direct competition.
   </p>
        <p>
      I'm a pragmatic person and I appreciate that the service provided by Stack Overflow
      is useful.
   </p>
        <p>
      Since I'm gaining value from the site on a regular basis now, it makes sense to try
      to help out and "give back" to the community by providing answers when possible.
   </p>
        <p>
      Stack Overflow is "good enough" to support.
   </p>
        <p>
      Also, while I believe the benefits of putting a Stack Overflow reputation number on
      a resume are overstated (and include some small amount of risk), I do think asking
      and answering questions on Stack Overflow is an important indirect marketing opportunity
      for individuals.  As one example, if a blog post I've written answers a question
      some one asked, answering the question on Stack Overflow with a pointer to my blog
      post is helpful and increases the useful life/value of that blog post.  I think
      blog posts are a great way to expand the programmer knowledge base, but not all blog
      posts will be easily found through Google searches (Providing links to your blog from
      Stack Overflow will not increase your blog's page rank, but people will click through
      none the less).
   </p>
        <img width="0" height="0" src="http://www.capprime.com/software_development_weblog/aggbug.ashx?id=45ec5ae4-34b1-4dc3-978e-1d8cbc964a36" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Capprime Lua Obfuscator v1.0.0.8 released 08/16/2009</title>
    <link rel="alternate" type="text/html" href="http://www.capprime.com/software_development_weblog/PermaLink,guid,6cf64205-165f-4fd8-a761-11a1cc7e3313.aspx" />
    <id>http://www.capprime.com/software_development_weblog/PermaLink,guid,6cf64205-165f-4fd8-a761-11a1cc7e3313.aspx</id>
    <published>2009-08-16T07:30:13.3435-04:00</published>
    <updated>2009-08-16T07:30:13.3435-04:00</updated>
    <category term="Lua Obfuscator" label="Lua Obfuscator" scheme="dasBlog" />
    <category term="Tools" label="Tools" scheme="dasBlog" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
      After a number of small releases focused on application infrastructure, this release
      is a semi-major user focused feature release.
   </p>
        <p>
      The biggest new feature is treating function parameters as obfuscatable variables.
   </p>
        <p>
      A user requested that function/variable names not grow in size as part of obfuscation,
      so function/variable names now stay the same size.  This may continue to be refined
      over time depending on what people think.
   </p>
        <p>
      Since this obfuscator was originally written for my own use, it made some assumptions
      about coding style, especially in regards to whitespace.  A number of those types
      of assumptions have now been removed based on testing against code submitted by users.
   </p>
        <p>
      While some substring type issues still remain, it is now possible to have local variables
      which are substrings of one another like "counter" and "counter1" without the obfuscator
      missing a beat.
   </p>
        <p>
      It used to be possible to have a variable named "funct" (which is a substring of the
      lua reserved word "function"), but this is no longer allowed.  More work is needed
      in this area (not mangling lua reserved words) going forward.
   </p>
        <p>
      The latest version of the Capprime Lua Obfuscator is available here:
   </p>
        <p>
          <a href="http://www.capprime.com/CapprimeLuaObfuscator/CapprimeLuaObfuscator.aspx">http://www.capprime.com/CapprimeLuaObfuscator/CapprimeLuaObfuscator.aspx</a>
        </p>
        <img width="0" height="0" src="http://www.capprime.com/software_development_weblog/aggbug.ashx?id=6cf64205-165f-4fd8-a761-11a1cc7e3313" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Capprime Lua Obfuscator v1.0.0.7 released 07/27/2009</title>
    <link rel="alternate" type="text/html" href="http://www.capprime.com/software_development_weblog/PermaLink,guid,6b9e2a3c-f5d6-4fab-877c-db7b94fc6c4e.aspx" />
    <id>http://www.capprime.com/software_development_weblog/PermaLink,guid,6b9e2a3c-f5d6-4fab-877c-db7b94fc6c4e.aspx</id>
    <published>2009-07-27T05:19:07.6005-04:00</published>
    <updated>2009-07-27T05:19:07.6005-04:00</updated>
    <category term="Lua Obfuscator" label="Lua Obfuscator" scheme="dasBlog" />
    <category term="Tools" label="Tools" scheme="dasBlog" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
      This release increases the number of characters that can be obfuscated at one time
      from 1000 to 3000.
   </p>
        <p>
      The daily character obfuscation limit has also been increased from 3000 to 6000.
   </p>
        <p>
      These limits may change again in the future depending on usage and feedback.
   </p>
        <p>
      The Capprime Lua Obfuscator is available here:
   </p>
        <p>
          <a href="http://www.capprime.com/CapprimeLuaObfuscator/CapprimeLuaObfuscator.aspx">http://www.capprime.com/CapprimeLuaObfuscator/CapprimeLuaObfuscator.aspx</a>
        </p>
        <img width="0" height="0" src="http://www.capprime.com/software_development_weblog/aggbug.ashx?id=6b9e2a3c-f5d6-4fab-877c-db7b94fc6c4e" />
      </div>
    </content>
  </entry>
</feed>