<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="https://www.w3.org/2005/Atom" xmlns:sy="https://purl.org/rss/1.0/modules/syndication/" xmlns:dc="https://purl.org/dc/elements/1.1/" xmlns:content="https://purl.org/rss/1.0/modules/content/" xmlns:wfw="https://wellformedweb.org/CommentAPI/" xmlns:slash="https://purl.org/rss/1.0/modules/slash/"
  version="2.0">
  <channel>
    <title>Patrick Sirr's Blog</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/psirr/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/psirr/feed.xml</link>
    <description>DataDude Notes</description>
    <lastBuildDate>Tue, 16 Apr 2019 05:26:35 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>Using T4 Templates with Visual Studio 2010 Database Projects</title>
      <link>https://docs.microsoft.com/archive/blogs/psirr/using-t4-templates-with-visual-studio-2010-database-projects</link>
      <pubDate>Tue, 12 Apr 2011 09:14:48 GMT</pubDate>
      <dc:creator><![CDATA[psirr-MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/psirr/2011/04/12/using-t4-templates-with-visual-studio-2010-database-projects/</guid>
      <description><![CDATA[&#160;  I had a request to update my Visual Studio 2008 GDR Database projects CRUD generator to...]]></description>
      <content:encoded><![CDATA[<p>&#160;</p>  <p>I had a request to update my Visual Studio 2008 GDR Database projects CRUD generator to Visual Studio 2010. Not much has changed except for some references and directory locations. The flow of the add-in is identical to the 2008 version. Below are the pertinent links. </p>  <p><a href="https://blogs.msdn.com/b/psirr/archive/2008/12/29/using-t4-templates-with-gdr-database-projects.aspx">Original blog entry</a></p>  <p><a href="https://cid-9743d44f2931a23d.office.live.com/self.aspx/Blogs/VS2010DBProj/CRUDGenerator.zip">Source Code</a></p>  <p><a href="https://cid-9743d44f2931a23d.office.live.com/self.aspx/Blogs/VS2010DBProj/InstallCRUDGenerator.msi">Visual Studio 2010 Database Projects CRUD Generator MSI</a></p>  <p>Please ping me if there are any issues. Thanks!</p>  <p>-- Patrick</p>]]></content:encoded>
    </item>
    <item>
      <title>Database Project Extensibility – Merge Table and View Scripts</title>
      <link>https://docs.microsoft.com/archive/blogs/psirr/database-project-extensibility-merge-table-and-view-scripts</link>
      <pubDate>Wed, 05 Jan 2011 12:36:20 GMT</pubDate>
      <dc:creator><![CDATA[psirr-MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/psirr/2011/01/05/database-project-extensibility-merge-table-and-view-scripts/</guid>
      <description><![CDATA[&#160;  In this blog I’ve created a project feature extension to combine Table and View child...]]></description>
      <content:encoded><![CDATA[<p>&#160;</p>  <p>In this blog I’ve created a project feature extension to combine Table and View child scripts into the script that defines the parent object. For example, constraints or extended properties for a table. Some developers like to have all the T-SQL scripts defining a particular object in one .sql file. Typically you’d run this after using Import Schema to populate your database project. The package is built using a <a href="https://blogs.msdn.com/quanto/archive/2009/05/26/what-is-a-vsix.aspx">vsix file</a> as the deployment mechanism and can be downloaded <a href="https://cid-9743d44f2931a23d.office.live.com/self.aspx/Blogs/MergeScripts/MergeScripts.vsix">here</a>. The source for this project is located <a href="https://cid-9743d44f2931a23d.office.live.com/self.aspx/Blogs/MergeScripts/MergeScripts.zip">here</a>. </p>  <h1>Overview of the Package</h1>  <h2>Adding the button to Schema View</h2>  <p>The package contributes a ‘Merge scripts into parent schema object’ menu button onto the schema view context menu for Tables and Views. When pressed the selected Tables and Views will gather their hierarchical statements into the parent script. If the child script is emptied of content then it is excluded from the project . If your project is under version control you may wish to review the output window and delete these files from your SCC provider.</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/15/39/metablogapi/8054.image_722D7178.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-15-39-metablogapi/8054.image_5F00_722D7178.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/15/39/metablogapi/1512.image_thumb_422AD20A.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-15-39-metablogapi/1512.image_5F00_thumb_5F00_422AD20A.png" width="412" height="288" /></a></p>    <p>Overview of the Code   <br />One of our requirements is to add a button to the Schema View context menu.&#160; In order to do that we’ll need to create a Visual Studio package.&#160; To create Visual Studio packages you’ll need to install the SDK located here.&#160; Once installed, you’ll have the option to create a new “Visual Studio Integration Package” project based on the vsix format.&#160;&#160; See the file ‘MergeScripts.vsct’ for details on how I added this button on the schema view context menu.&#160; </p>  <p>&#160;</p>  <h2>Implementing the database project feature extension</h2>  <p>I also need to hook into the Visual Studio 2010 database project extensibility. To create extensions to a Visual Studio 2010 database project you must </p>  <p>&#160;</p>  <ul>   <li>Create a class which implements one of the extension point interfaces. All these interfaces ultimately derive from Microsoft.Data.Schema.Extensibility.IExtension.</li>    <li>Publish your extension via a file named &lt;MyFile&gt;.Extensions.xml file which can be placed in the %ProgramFiles%\Microsoft Visual Studio 10.0\VSTSDB, %ProgramFiles%\Microsoft Visual Studio 10.0\Common7\IDE or the %LocalAppData%\Microsoft\VisualStudio\10.0&lt;hive&gt;\Extensions directory.</li>    <li>Your extensions file must correspond to the following schema:</li> </ul>  <p>&#160;</p>  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:a7075f7d-f640-4c92-9c6b-dbfa66ab6566" class="wlWriterEditableSmartContent"><pre style=" width: 809px; height: 289px;background-color:White;overflow: auto;"><div><!--

code highlighting produced by Actipro CodeHighlighter (freeware)
https://www.CodeHighlighter.com/

--><span style="color: #000000;">&lt;?</span><span style="color: #000000;">xml version</span><span style="color: #000000;">=</span><span style="color: #800000;">&quot;</span><span style="color: #800000;">1.0</span><span style="color: #800000;">&quot;</span><span style="color: #000000;"> encoding</span><span style="color: #000000;">=</span><span style="color: #800000;">&quot;</span><span style="color: #800000;">utf-8</span><span style="color: #800000;">&quot;</span><span style="color: #000000;">?&gt;</span><span style="color: #000000;">
</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">xsd:schema xmlns:xsd</span><span style="color: #000000;">=</span><span style="color: #800000;">&quot;</span><span style="color: #800000;">https://www.w3.org/2001/XMLSchema</span><span style="color: #800000;">&quot;</span><span style="color: #000000;"> xmlns</span><span style="color: #000000;">=</span><span style="color: #800000;">&quot;</span><span style="color: #800000;">urn:Microsoft.Data.Schema.Extensions</span><span style="color: #800000;">&quot;</span><span style="color: #000000;"> elementFormDefault</span><span style="color: #000000;">=</span><span style="color: #800000;">&quot;</span><span style="color: #800000;">qualified</span><span style="color: #800000;">&quot;</span><span style="color: #000000;"> attributeFormDefault</span><span style="color: #000000;">=</span><span style="color: #800000;">&quot;</span><span style="color: #800000;">unqualified</span><span style="color: #800000;">&quot;</span><span style="color: #000000;"> targetNamespace</span><span style="color: #000000;">=</span><span style="color: #800000;">&quot;</span><span style="color: #800000;">urn:Microsoft.Data.Schema.Extensions</span><span style="color: #800000;">&quot;</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
  </span><span style="color: #000000;">&lt;</span><span style="color: #000000;">xsd:element name</span><span style="color: #000000;">=</span><span style="color: #800000;">&quot;</span><span style="color: #800000;">extensions</span><span style="color: #800000;">&quot;</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
    </span><span style="color: #000000;">&lt;</span><span style="color: #000000;">xsd:complexType</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
      </span><span style="color: #000000;">&lt;</span><span style="color: #000000;">xsd:sequence</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
        </span><span style="color: #000000;">&lt;</span><span style="color: #000000;">xsd:element name</span><span style="color: #000000;">=</span><span style="color: #800000;">&quot;</span><span style="color: #800000;">extension</span><span style="color: #800000;">&quot;</span><span style="color: #000000;"> minOccurs</span><span style="color: #000000;">=</span><span style="color: #800000;">&quot;</span><span style="color: #800000;">0</span><span style="color: #800000;">&quot;</span><span style="color: #000000;"> maxOccurs</span><span style="color: #000000;">=</span><span style="color: #800000;">&quot;</span><span style="color: #800000;">unbounded</span><span style="color: #800000;">&quot;</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
          </span><span style="color: #000000;">&lt;</span><span style="color: #000000;">xsd:complexType</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
            </span><span style="color: #000000;">&lt;</span><span style="color: #000000;">xsd:attribute name</span><span style="color: #000000;">=</span><span style="color: #800000;">&quot;</span><span style="color: #800000;">assembly</span><span style="color: #800000;">&quot;</span><span style="color: #000000;"> type</span><span style="color: #000000;">=</span><span style="color: #800000;">&quot;</span><span style="color: #800000;">xsd:string</span><span style="color: #800000;">&quot;</span><span style="color: #000000;"> use</span><span style="color: #000000;">=</span><span style="color: #800000;">&quot;</span><span style="color: #800000;">optional</span><span style="color: #800000;">&quot;</span><span style="color: #000000;">/&gt;</span><span style="color: #000000;">
            </span><span style="color: #000000;">&lt;</span><span style="color: #000000;">xsd:attribute name</span><span style="color: #000000;">=</span><span style="color: #800000;">&quot;</span><span style="color: #800000;">type</span><span style="color: #800000;">&quot;</span><span style="color: #000000;"> type</span><span style="color: #000000;">=</span><span style="color: #800000;">&quot;</span><span style="color: #800000;">xsd:string</span><span style="color: #800000;">&quot;</span><span style="color: #000000;"> use</span><span style="color: #000000;">=</span><span style="color: #800000;">&quot;</span><span style="color: #800000;">required</span><span style="color: #800000;">&quot;</span><span style="color: #000000;">/&gt;</span><span style="color: #000000;">
            </span><span style="color: #000000;">&lt;</span><span style="color: #000000;">xsd:attribute name</span><span style="color: #000000;">=</span><span style="color: #800000;">&quot;</span><span style="color: #800000;">enabled</span><span style="color: #800000;">&quot;</span><span style="color: #000000;"> type</span><span style="color: #000000;">=</span><span style="color: #800000;">&quot;</span><span style="color: #800000;">xsd:boolean</span><span style="color: #800000;">&quot;</span><span style="color: #000000;"> use</span><span style="color: #000000;">=</span><span style="color: #800000;">&quot;</span><span style="color: #800000;">required</span><span style="color: #800000;">&quot;</span><span style="color: #000000;">/&gt;</span><span style="color: #000000;">
          </span><span style="color: #000000;">&lt;/</span><span style="color: #000000;">xsd:complexType</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
        </span><span style="color: #000000;">&lt;/</span><span style="color: #000000;">xsd:element</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
      </span><span style="color: #000000;">&lt;/</span><span style="color: #000000;">xsd:sequence</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
      </span><span style="color: #000000;">&lt;</span><span style="color: #000000;">xsd:attribute name</span><span style="color: #000000;">=</span><span style="color: #800000;">&quot;</span><span style="color: #800000;">assembly</span><span style="color: #800000;">&quot;</span><span style="color: #000000;"> type</span><span style="color: #000000;">=</span><span style="color: #800000;">&quot;</span><span style="color: #800000;">xsd:string</span><span style="color: #800000;">&quot;</span><span style="color: #000000;"> use</span><span style="color: #000000;">=</span><span style="color: #800000;">&quot;</span><span style="color: #800000;">required</span><span style="color: #800000;">&quot;</span><span style="color: #000000;">/&gt;</span><span style="color: #000000;">
      </span><span style="color: #000000;">&lt;</span><span style="color: #000000;">xsd:attribute name</span><span style="color: #000000;">=</span><span style="color: #800000;">&quot;</span><span style="color: #800000;">version</span><span style="color: #800000;">&quot;</span><span style="color: #000000;"> type</span><span style="color: #000000;">=</span><span style="color: #800000;">&quot;</span><span style="color: #800000;">xsd:unsignedByte</span><span style="color: #800000;">&quot;</span><span style="color: #000000;"> use</span><span style="color: #000000;">=</span><span style="color: #800000;">&quot;</span><span style="color: #800000;">required</span><span style="color: #800000;">&quot;</span><span style="color: #000000;">/&gt;</span><span style="color: #000000;">
    </span><span style="color: #000000;">&lt;/</span><span style="color: #000000;">xsd:complexType</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
  </span><span style="color: #000000;">&lt;/</span><span style="color: #000000;">xsd:element</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
</span><span style="color: #000000;">&lt;/</span><span style="color: #000000;">xsd:schema</span><span style="color: #000000;">&gt;</span></!--

code></div></pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  https://dunnhq.com --></!--></div>

<p>The database extension created for this project is called MergeScriptsFeature and is published in the MergeScripts.Extensions.xml:</p>

<p>&#160;</p>

<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:fc19dd09-f512-45cf-8f8f-8a805827dc46" class="wlWriterEditableSmartContent"><pre style=" width: 809px; height: 96px;background-color:White;overflow: auto;"><div><!--

code highlighting produced by Actipro CodeHighlighter (freeware)
https://www.CodeHighlighter.com/

--><span style="color: #000000;">&lt;?</span><span style="color: #000000;">xml version</span><span style="color: #000000;">=</span><span style="color: #800000;">&quot;</span><span style="color: #800000;">1.0</span><span style="color: #800000;">&quot;</span><span style="color: #000000;"> encoding</span><span style="color: #000000;">=</span><span style="color: #800000;">&quot;</span><span style="color: #800000;">utf-8</span><span style="color: #800000;">&quot;</span><span style="color: #000000;">?&gt;</span><span style="color: #000000;">
</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">extensions assembly</span><span style="color: #000000;">=</span><span style="color: #800000;">&quot;&quot;</span><span style="color: #000000;"> version</span><span style="color: #000000;">=</span><span style="color: #800000;">&quot;</span><span style="color: #800000;">1</span><span style="color: #800000;">&quot;</span><span style="color: #000000;"> xmlns</span><span style="color: #000000;">=</span><span style="color: #800000;">&quot;</span><span style="color: #800000;">urn:Microsoft.Data.Schema.Extensions</span><span style="color: #800000;">&quot;</span><span style="color: #000000;"> xmlns:xsi</span><span style="color: #000000;">=</span><span style="color: #800000;">&quot;</span><span style="color: #800000;">https://www.w3.org/2001/XMLSchema-instance</span><span style="color: #800000;">&quot;</span><span style="color: #000000;"> xsi:schemaLocation</span><span style="color: #000000;">=</span><span style="color: #800000;">&quot;</span><span style="color: #800000;">urn:Microsoft.Data.Schema.Extensions Microsoft.Data.Schema.Extensions.xsd</span><span style="color: #800000;">&quot;</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
  </span><span style="color: #000000;">&lt;</span><span style="color: #000000;">extension type</span><span style="color: #000000;">=</span><span style="color: #800000;">&quot;</span><span style="color: #800000;">MergeScripts.MergeScriptsFeature</span><span style="color: #800000;">&quot;</span><span style="color: #000000;"> assembly</span><span style="color: #000000;">=</span><span style="color: #800000;">&quot;</span><span style="color: #800000;">MergeScripts, Version=1.0.0.0, Culture=neutral, PublicKeyToken=0cae59df434c3018</span><span style="color: #800000;">&quot;</span><span style="color: #000000;">  enabled</span><span style="color: #000000;">=</span><span style="color: #800000;">&quot;</span><span style="color: #800000;">true</span><span style="color: #800000;">&quot;</span><span style="color: #000000;"> </span><span style="color: #000000;">/&gt;</span><span style="color: #000000;">
</span><span style="color: #000000;">&lt;/</span><span style="color: #000000;">extensions</span><span style="color: #000000;">&gt;</span></!--

code></div></pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  https://dunnhq.com --></!--></div>

<p>MergeScriptsFeature has the following declaration:</p>

<p>[DatabaseSchemaProviderCompatibility(typeof(SqlDatabaseSchemaProvider))]</p>

<p>class MergeScriptsFeature : IDatabaseProjectFeature, IOleCommandTarget</p>

<p>The DatabaseSchemaProviderCompatibility attribute identifies the database schema provider affinity. In this case “SqlDatabaseSchemaProvider” is used indicating that this feature will work with all SQL database projects.</p>

<p>When a database project is opened it queries for all extensions compatible with the current database schema provider which also implement IDatabaseProjectFeature. Instances of each of those features are instantiated and initialized with the IDatabaseProjectNode for that project. With this node, features can listen to events – in my case I listen to ProjectClosed and FileIconRequest.</p>

<p>The MergeScriptsFeature will need to chain into the IOleCommandTarget implemented by the Database Schema View. To do this the feature retrieves the ‘SchemaModelViewerService’ from the agnostic database package – called ‘DataPackage’. Once that service raises the DatabaseSchemaViewInitialized event (or if the Schema View is already displayed) the MergeScriptsFeature IOleCommandTarget is chained through the method IDatabaseSchemaView.RegisterForLimitedCommandRouting.</p>

<p>When the merge button is pressed MergeScriptsFeature.DoMerge() is called. This routine creates a CommandFactory and proceeds to buffer up the source code control and file operations necessary to do the actual merge. Once all these commands are buffered they are ordered and executed in CommandFactory.Execute().</p>

<p>&#160;</p>

<h2>Installing the Package</h2>

<p>Installing a vsix package can be done on a per-user basis or for all users on the machine. To install as a specific user just double-click on the .vsix file. This will unzip the contents and place them into “%LocalAppData%\Microsoft\VisualStudio\10.0Exp\Extensions\Microsoft Corporation\MergeScripts\1.0”. The next time Visual Studio is launched the contents of this package (like menu definitions) will be merged into the Visual Studio shell. To verify the vsix extension is installed bring up the Extension Manager available under the main menu “Tools.Extension Manager”. You should see the MergeScripts package.</p>

<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/15/39/metablogapi/0458.image_12038747.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-15-39-metablogapi/0458.image_5F00_12038747.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/15/39/metablogapi/4657.image_thumb_717C4794.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-15-39-metablogapi/4657.image_5F00_thumb_5F00_717C4794.png" width="637" height="442" /></a></p>

<p>To install the vsix package for all users (called a Trusted Extension) you need to have administrator rights on the machine. You can then install using the “VSIXInstaller /admin” command. This will install the extension into %VSInstallDir%\Common7\IDE\Extensions.</p>

<p>&#160;</p>

<h2>Conclusion</h2>

<p>I know an extension like this (or an option during Import Script) has been requested multiple times on our forums. Until we get around to adding the option into Visual Studio I hope this extension will service your needs. If you have any questions please visit our forums <a href="https://social.msdn.microsoft.com/Forums/en-US/vstsdb/threads">here</a> or contact me via this blog. Thanks!</p>

<p>-- Patrick</p>]]></content:encoded>
    </item>
    <item>
      <title>Template Driven Sql Generation Updated for Visual Studio 2010</title>
      <link>https://docs.microsoft.com/archive/blogs/psirr/template-driven-sql-generation-updated-for-visual-studio-2010</link>
      <pubDate>Tue, 28 Dec 2010 20:46:03 GMT</pubDate>
      <dc:creator><![CDATA[psirr-MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/psirr/2010/12/28/template-driven-sql-generation-updated-for-visual-studio-2010/</guid>
      <description><![CDATA[More than a year ago I presented a simple template processor for Visual Studio 2008 Database...]]></description>
      <content:encoded><![CDATA[<p>More than a year ago I presented a simple template processor for Visual Studio 2008 Database Projects. This add-in gives you the ability to write Transact-SQL in a simple template form with embedded SQLCMD variables. It’ll turn</p>  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:9219fdcb-3275-4862-86ae-bbf377d326ed" class="wlWriterEditableSmartContent"><pre style=" width: 356px; height: 136px;background-color:White;overflow: auto;"><div><!--

code highlighting produced by Actipro CodeHighlighter (freeware)
https://www.CodeHighlighter.com/

--><span style="color: #000000;">--*</span><span style="color: #000000;">CREATE TABLE [dbo].[$(MyVar)]
</span><span style="color: #000000;">--*</span><span style="color: #000000;">(
</span><span style="color: #000000;">--*</span><span style="color: #000000;"> column_1 </span><span style="color: #0000FF;">int</span><span style="color: #000000;"> NOT NULL, 
</span><span style="color: #000000;">--*</span><span style="color: #000000;"> column_2 </span><span style="color: #0000FF;">int</span><span style="color: #000000;"> NULL
</span><span style="color: #000000;">--*</span><span style="color: #000000;">)</span></!--

code></div></pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  https://dunnhq.com --></!--></div>

<p>Into valid Transact-SQL</p>

<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:1951a415-0846-49c7-b2ff-e115d0753bdf" class="wlWriterEditableSmartContent"><pre style=" width: 359px; height: 140px;background-color:White;overflow: auto;"><div><!--

code highlighting produced by Actipro CodeHighlighter (freeware)
https://www.CodeHighlighter.com/

--><span style="color: #000000;">CREATE TABLE [dbo].[MyReleaseTableName]
(
column_1 </span><span style="color: #0000FF;">int</span><span style="color: #000000;"> NOT NULL, 
column_2 </span><span style="color: #0000FF;">int</span><span style="color: #000000;"> NULL
) 

</span></!--

code></div></pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  https://dunnhq.com --></!--></div>

<p>I’ve updated the add-in to work with Visual Studio 2010. The essential details haven’t changed so please refer to my <a href="https://blogs.msdn.com/b/psirr/archive/2009/07/31/template-driven-sql-generation.aspx">past post</a>. If you wish to recompile the source you’ll need Visual Studio 2010 (professional or ultimate) and the <a href="https://wix.sourceforge.net/releases/3.6.1222.0/data/">Wix Toolset</a>.</p>

<p>The source code for the Visual Studio ProcessSqlTemplate MSBuild Task and Add-in is <a href="https://cid-9743d44f2931a23d.office.live.com/self.aspx/Blogs/ProcessTemplateDev10/InstallProcessSqlTemplate.zip">here</a>.</p>

<p>The ProcessSqlTemplateAddIn MSI is located <a href="https://cid-9743d44f2931a23d.office.live.com/self.aspx/Blogs/ProcessTemplateDev10/InstallProcessSqlTemplate.msi">here</a>.<del datetime="2009-07-28T12:34" cite="mailto:Duke%20Kamstra"></del></p>]]></content:encoded>
    </item>
    <item>
      <title>Converting .dbp files to .dbproj files</title>
      <link>https://docs.microsoft.com/archive/blogs/psirr/converting-dbp-files-to-dbproj-files</link>
      <pubDate>Mon, 16 Nov 2009 15:27:19 GMT</pubDate>
      <dc:creator><![CDATA[psirr-MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/psirr/2009/11/16/converting-dbp-files-to-dbproj-files/</guid>
      <description><![CDATA[With the release of Visual Studio 2010 Beta 2, database projects with the .dbp extension are...]]></description>
      <content:encoded><![CDATA[<p>With the release of Visual Studio 2010 Beta 2, database projects with the .dbp extension are deprecated. There are several ways to convert your project manually </p>  <ul>   <li>Import Script. Unfortunately this will shred your scripts for schema objects and move any conditional logic into the scriptsignored file. </li>    <li>Add Existing Item. You could create a Visual Studio 2010 project and use “Add Existing Item” to bring your .dbp scripts into your new project. The downside with this is 1) it is time consuming and 2) you lose the workspace the version control provider needs – therefore loosing history of your files. </li>    <li>“Include In Project”. Create a new Visual Studio 2010 project and drag your .dbp project folder structure on the top of the .dbproj file. After your finished select “Show All Items” from the Visual Studio 2010 Solution Explorer and then “Include In Project” for your .dbp files. Unless you create the new .dbproj project over the top of your .dbp project you’ll lose version control history. </li> </ul>  <h4>DbpToDbproj.exe</h4>  <p>To help Database Project (.dbp) customers with the upgrade to Visual Studio 2010 I’ve written DbpToDbProj. The source and executable is located <a href="https://cid-9743d44f2931a23d.skydrive.live.com/self.aspx/Blogs/DbpToDbproj.zip">here</a>.</p>  <p>This project builds a command-line executable with parameters allowing you to create either a Visual Studio 2010 2005DSP or 2008DSP project, and indicate if the file structure for the ‘Schema Objects’ folder is ‘by schema’ or ‘by type’.</p>  <div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">   <div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet">     <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum1">   1:</span> c:\Temp<span style="color: #0000ff">&gt;</span>DbpToDbproj<span style="color: #ff0000">.</span>exe /<span style="color: #cc6633">?</span></pre>
<!--CRLF-->

    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum2">   2:</span> Database projects that have the file extension <span style="color: #ff0000">.</span>dbp have been deprecated in Visual Studio 2010</pre>
<!--CRLF-->

    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum3">   3:</span> DbpToDbproj creates a database project with the <span style="color: #ff0000">.</span>dbproj extension to replace the dbp<span style="color: #ff0000">.</span></pre>
<!--CRLF-->

    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum4">   4:</span>&#160; </pre>
<!--CRLF-->

    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum5">   5:</span> DbpToDbproj [drive:][path]filename [/target:[2005|2008]] [/DefaultFileStructure:[ByType | BySchema]]</pre>
<!--CRLF-->

    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum6">   6:</span> [drive:][path]filename</pre>
<!--CRLF-->

    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum7">   7:</span> Specifies drive, directory and filename for the dbp file to be converted<span style="color: #ff0000">.</span></pre>
<!--CRLF-->

    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum8">   8:</span>&#160; </pre>
<!--CRLF-->

    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum9">   9:</span> /target:[2005|2008]</pre>
<!--CRLF-->

    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum10">  10:</span> Specifies whether the <span style="color: #ff0000">.</span>dbproj to be created is a Sql2005 or a Sql2008 project<span style="color: #ff0000">.</span></pre>
<!--CRLF-->

    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum11">  11:</span>&#160; </pre>
<!--CRLF-->

    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum12">  12:</span> /DefaultFileStructure:[ByType | BySchema]]</pre>
<!--CRLF-->

    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum13">  13:</span> Specifies whether the directory structure of the <span style="color: #ff0000">.</span>dbproj should be by object schema or type<span style="color: #ff0000">.</span></pre>
<!--CRLF--></div>
</div>

<p>Specifies whether the directory structure of the .dbproj should be by object schema or type.</p>

<p>As an example, here’s a .dbp project from Visual Studio 2008:</p>

<p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/psirr/WindowsLiveWriter/Converting.dbpfilesto.dbprojfiles_D955/clip_image002_2.jpg" original-url="https://blogs.msdn.com/blogfiles/psirr/WindowsLiveWriter/Converting.dbpfilesto.dbprojfiles_D955/clip_image002_2.jpg"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image002" border="0" alt="clip_image002" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/psirr/WindowsLiveWriter/Converting.dbpfilesto.dbprojfiles_D955/clip_image002_thumb.jpg" original-url="https://blogs.msdn.com/blogfiles/psirr/WindowsLiveWriter/Converting.dbpfilesto.dbprojfiles_D955/clip_image002_thumb.jpg" width="264" height="272" /></a></p>

<p>Running DspToDbproj in the same directory as your existing .dbp project will create a file called ‘&lt;dbpfilename&gt;.dbproj’.</p>

<div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
  <div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet">
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum1">   1:</span> C:\Temp\dbpProject\dbpProject&gt;DbpToDbproj.exe dbpProject.dbp</pre>
<!--CRLF-->

    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum2">   2:</span> Converting...</pre>
<!--CRLF-->

    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum3">   3:</span> C:\Temp\dbpProject\dbpProject\dbpProject.dbp</pre>
<!--CRLF-->

    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum4">   4:</span> ...to...</pre>
<!--CRLF-->

    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum5">   5:</span> C:\Temp\dbpProject\dbpProject\dbpProject.dbproj</pre>
<!--CRLF-->

    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum6">   6:</span> Successfully converted dbp to C:\Temp\dbpProject\dbpProject\dbpProject.dbproj</pre>
<!--CRLF--></div>
</div>

<p>When the .dbproj file is opened you’ll receive an upgrade prompt.&#160; The reason for this is that my command-line utility does not interact with your Version Control system.&#160; Instead I place an MSBuild property in the dbproj file called “PostUpgradeAddToSCC”.&#160; This property is a flag to the database project system that upgrade has added new files and that these new files should be added to SCC.&#160; This only happens after the upgrade process so I had to make the system think an upgrade was necessary.&#160; If you don’t use version control you can edit Program.cs and remove the line where I create the “PreviousProjectVersion” MSBuild property.&#160; The absence of this property will prevent the upgrade wizard from appearing.</p>

<p>After opening the .dbproj file the following project will appear in the solution. Notice that the script files are maintained as they were in the .dbp project. Each of these script files have a build action of ‘Not In Build’, meaning they do not contribute to the dbproj model. It also creates the standard “Schema Objects”, “Data Generation Plans”, and “Schema Comparisons” folders you’d get with any other Visual Studio 2010 project. If you’re using the new Database Project (.dbproj) project for purely version control you can always delete these directories – otherwise you’ll still be able to import from an existing database or a script.</p>

<p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/psirr/WindowsLiveWriter/Converting.dbpfilesto.dbprojfiles_D955/image_2.png" original-url="https://blogs.msdn.com/blogfiles/psirr/WindowsLiveWriter/Converting.dbpfilesto.dbprojfiles_D955/image_2.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/psirr/WindowsLiveWriter/Converting.dbpfilesto.dbprojfiles_D955/image_thumb.png" original-url="https://blogs.msdn.com/blogfiles/psirr/WindowsLiveWriter/Converting.dbpfilesto.dbprojfiles_D955/image_thumb.png" width="244" height="373" /></a> </p>

<p>DspToDbproj will preserve the connections found in the .dbp by writing them into a file called Connections.txt. From these connection strings you should be able to recreate the connection in the Server Explorer manually.</p>

<h4>Conclusion</h4>

<p>Hopefully this will make the conversion to Visual Studio 2010 a little easier for everyone with .dbp projects. Once again the source and executable is located <a href="https://cid-9743d44f2931a23d.skydrive.live.com/self.aspx/Blogs/DbpToDbproj.zip">here</a>. If you have any questions please visit our forums <a href="https://social.msdn.microsoft.com/Forums/en-US/vstsdb/threads">here</a> or ping me through this blog.&#160; Thanks!</p>

<p>-- Patrick</p>]]></content:encoded>
    </item>
    <item>
      <title>Interesting Memory Leak in .Net 3.5 Binary Deserialization</title>
      <link>https://docs.microsoft.com/archive/blogs/psirr/interesting-memory-leak-in-net-3-5-binary-deserialization</link>
      <pubDate>Fri, 13 Nov 2009 09:35:17 GMT</pubDate>
      <dc:creator><![CDATA[psirr-MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/psirr/2009/11/13/interesting-memory-leak-in-net-3-5-binary-deserialization/</guid>
      <description><![CDATA[Recently I was analyzing an application written in managed code for memory problems.&#160; In...]]></description>
      <content:encoded><![CDATA[<p>Recently I was analyzing an application written in managed code for memory problems.&#160; In managed code a common cause of eating up memory is statically allocated objects which are not nulled out after they are no longer needed.</p>  <p>In the application I was debugging it was making use of binary deserialization to reconstruct a graph of objects. Many of these objects needed some additional context so a StreamingContext object was created with an additional context state. Here’s a sample of what the code was doing:</p>  <div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 98.22%; padding-right: 4px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; height: 210px; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">   <div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet">     <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum1">   1:</span> <span style="color: #0000ff">using</span> (FileStream fs = myfile.OpenRead())</pre>
<!--CRLF-->

    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum2">   2:</span> {</pre>
<!--CRLF-->

    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum3">   3:</span>     ContextObject ct = <span style="color: #0000ff">new</span> ContextObject();</pre>
<!--CRLF-->

    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum4">   4:</span>     ct.Name = <span style="color: #006080">&quot;testing&quot;</span>;</pre>
<!--CRLF-->

    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum5">   5:</span>     StreamingContext context = <span style="color: #0000ff">new</span> StreamingContext(StreamingContextStates.Other, ct);</pre>
<!--CRLF-->

    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum6">   6:</span>     BinaryFormatter bf = <span style="color: #0000ff">new</span> BinaryFormatter();</pre>
<!--CRLF-->

    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum7">   7:</span>     bf.Context = context;</pre>
<!--CRLF-->

    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum8">   8:</span>     SerializableObject obj = (SerializableObject)bf.Deserialize(fs);</pre>
<!--CRLF-->

    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum9">   9:</span> }</pre>
<!--CRLF--></div>
</div>

<p>Everything was working well until I noticed that deserialization would consistently increase the memory footprint (recognize that, in my case, the additional context object was quite large). I wrote a sample application analyzed the problem using WinDBG. The sample program is located <a href="https://cid-9743d44f2931a23d.skydrive.live.com/self.aspx/Blogs/LeakApplication.zip">here</a>.</p>

<p>Open WinDBG and select “Open Executable”. Select LeakApplication.exe and hit F5. LeakApplication will run waiting for console input. Select ‘Break’ in WinDBG and type “!dumpheap -type LeakApplication.ContextObject”. You’ll see something like this:</p>

<div id="codeSnippetWrapper">
  <div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet">
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum1">   1:</span> 0:003<span style="color: #0000ff">&gt;</span> !dumpheap -type LeakApplication<span style="color: #ff0000">.</span>ContextObject</pre>
<!--CRLF-->

    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum2">   2:</span>  Address       MT     Size</pre>
<!--CRLF-->

    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum3">   3:</span> 01f6b7b0 0042340c       12     </pre>
<!--CRLF-->

    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum4">   4:</span> total 1 objects</pre>
<!--CRLF-->

    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum5">   5:</span> Statistics:</pre>
<!--CRLF-->

    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum6">   6:</span>       MT    Count    TotalSize Class Name</pre>
<!--CRLF-->

    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum7">   7:</span> 0042340c        1           12 LeakApplication<span style="color: #ff0000">.</span>ContextObject</pre>
<!--CRLF-->

    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum8">   8:</span> Total 1 objects</pre>
<!--CRLF--></div>
</div>

<p>WinDBG is telling us that 1 LeakApplication.ContextObject may be in memory. In order to determine if this is accurate type “!gcroot 01f6b7b0”. Here are the results:</p>

<div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 100.76%; padding-right: 4px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; height: 270px; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
  <div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet">
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum1">   1:</span> 0:003<span style="color: #0000ff">&gt;</span> !gcroot 01f6b7b0 </pre>
<!--CRLF-->

    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum2">   2:</span> Note: Roots found on stacks may be false positives<span style="color: #ff0000">.</span> Run &quot;!help gcroot&quot; for</pre>
<!--CRLF-->

    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum3">   3:</span> more info<span style="color: #ff0000">.</span></pre>
<!--CRLF-->

    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum4">   4:</span> Scan Thread 0 OSTHread 12f0</pre>
<!--CRLF-->

    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum5">   5:</span> ESP:20ef20:Root:01fcb148(System<span style="color: #ff0000">.</span>Runtime<span style="color: #ff0000">.</span>Serialization<span style="color: #ff0000">.</span>Formatters<span style="color: #ff0000">.</span>Binary<span style="color: #ff0000">.</span>BinaryFormatter)-<span style="color: #0000ff">&gt;</span></pre>
<!--CRLF-->

    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum6">   6:</span> 01f6b7b0(LeakApplication<span style="color: #ff0000">.</span>ContextObject)</pre>
<!--CRLF-->

    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum7">   7:</span> ESP:20ef3c:Root:01f6b7b0(LeakApplication<span style="color: #ff0000">.</span>ContextObject)-<span style="color: #0000ff">&gt;</span></pre>
<!--CRLF-->

    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum8">   8:</span> 01f6b7b0(LeakApplication<span style="color: #ff0000">.</span>ContextObject)</pre>
<!--CRLF-->

    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum9">   9:</span> ESP:20ef40:Root:01f6b7bc(System<span style="color: #ff0000">.</span>Runtime<span style="color: #ff0000">.</span>Serialization<span style="color: #ff0000">.</span>Formatters<span style="color: #ff0000">.</span>Binary<span style="color: #ff0000">.</span>BinaryFormatter)-<span style="color: #0000ff">&gt;</span></pre>
<!--CRLF-->

    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum10">  10:</span> 01f6b7b0(LeakApplication<span style="color: #ff0000">.</span>ContextObject)</pre>
<!--CRLF-->

    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum11">  11:</span> ESP:20ef54:Root:01f6b7b0(LeakApplication<span style="color: #ff0000">.</span>ContextObject)-<span style="color: #0000ff">&gt;</span></pre>
<!--CRLF-->

    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum12">  12:</span> 01f6b7b0(LeakApplication<span style="color: #ff0000">.</span>ContextObject)</pre>
<!--CRLF-->

    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum13">  13:</span> Scan Thread 2 OSTHread a28</pre>
<!--CRLF-->

    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum14">  14:</span> DOMAIN(002F1DE8):HANDLE(Pinned):4013fc:Root:02f51010(System<span style="color: #ff0000">.</span>Object[])-<span style="color: #0000ff">&gt;</span></pre>
<!--CRLF-->

    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum15">  15:</span> 01f6ad88(System<span style="color: #ff0000">.</span>Collections<span style="color: #ff0000">.</span>Generic<span style="color: #ff0000">.</span>Dictionary`2[[System<span style="color: #ff0000">.</span>Runtime<span style="color: #ff0000">.</span>Serialization<span style="color: #ff0000">.</span>MemberHolder, mscorlib],[System<span style="color: #ff0000">.</span>Reflection<span style="color: #ff0000">.</span>MemberInfo[], mscorlib]])-<span style="color: #0000ff">&gt;</span></pre>
<!--CRLF-->

    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum16">  16:</span> 01f6ae5c(System<span style="color: #ff0000">.</span>Collections<span style="color: #ff0000">.</span>Generic<span style="color: #ff0000">.</span>Dictionary`2+Entry[[System<span style="color: #ff0000">.</span>Runtime<span style="color: #ff0000">.</span>Serialization<span style="color: #ff0000">.</span>MemberHolder, mscorlib],[System<span style="color: #ff0000">.</span>Reflection<span style="color: #ff0000">.</span>MemberInfo[], mscorlib]][])-<span style="color: #0000ff">&gt;</span></pre>
<!--CRLF-->

    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum17">  17:</span> 01f6cb5c(System<span style="color: #ff0000">.</span>Runtime<span style="color: #ff0000">.</span>Serialization<span style="color: #ff0000">.</span>MemberHolder)-<span style="color: #0000ff">&gt;</span></pre>
<!--CRLF-->

    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum18">  18:</span> 01f6b7b0(LeakApplication<span style="color: #ff0000">.</span>ContextObject)</pre>
<!--CRLF--></div>
</div>

<p>Sure enough the BinaryFormatter is holding onto the LeakApplication.ContextObject. This is a known leak and, unfortunately, the best you can do is to mitigate the problem. In my case I created a small, disposable property bag object to hold onto my larger “additional” context objects. After deserialization simply call Dispose on the property bag and let it NULL out any members, thus clipping the object graph. Your property bag will still leak, but at least your larger object graph will be available for garbage collection.</p>

<p>-- Patrick</p>]]></content:encoded>
    </item>
    <item>
      <title>Sample Visual Studio 2008 Fonts and Color Provider</title>
      <link>https://docs.microsoft.com/archive/blogs/psirr/sample-visual-studio-2008-fonts-and-color-provider</link>
      <pubDate>Fri, 13 Nov 2009 09:02:05 GMT</pubDate>
      <dc:creator><![CDATA[psirr-MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/psirr/2009/11/13/sample-visual-studio-2008-fonts-and-color-provider/</guid>
      <description><![CDATA[Adding a new Font and Color category to the Visual Studio Options dialog is, admittedly, a little...]]></description>
      <content:encoded><![CDATA[<p>Adding a new Font and Color category to the Visual Studio Options dialog is, admittedly, a little tricky. There are several services your package must proffer, an interface you must implement and registry keys you must provide (one of them very poorly named!). I was recently asked to provide a fully working sample to help with a debugging session so I thought I’d share it.</p>  <p>For this blog I found two exceptional resources. Dr Ex. has a good blog post about the process for contributing to the Visual Studio fonts and colors dialog located <a href="https://blogs.msdn.com/dr._ex/archive/2005/06/03/425099.aspx">here</a>. There was also a post by Matthew Etter located <a href="https://www.dotnetmonster.com/Uwe/Forum.aspx/vs-ext/937/IVsFontAndColorDefaultsProvider-IVsFontAndColorDefaults-how-to-do">here</a> about creating a derived RegistrationAttribute to construct the necessary Visual Studio keys. Going from those postings to an actual working contributor is still a bit of a challenge though.</p>  <p>The sample involves one package which contributes a “FontAndColorCategory” to the Options dialog. It also contributes one color called “MyColor”.</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/psirr/WindowsLiveWriter/SampleVisualStudio2008FontsandColorProvi_7F08/clip_image002_2.jpg" original-url="https://blogs.msdn.com/blogfiles/psirr/WindowsLiveWriter/SampleVisualStudio2008FontsandColorProvi_7F08/clip_image002_2.jpg"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image002" border="0" alt="clip_image002" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/psirr/WindowsLiveWriter/SampleVisualStudio2008FontsandColorProvi_7F08/clip_image002_thumb.jpg" original-url="https://blogs.msdn.com/blogfiles/psirr/WindowsLiveWriter/SampleVisualStudio2008FontsandColorProvi_7F08/clip_image002_thumb.jpg" width="486" height="281" /></a></p>  <p>The aforementioned blog posts and msdn help should be able you to navigate and understand the source so I’m not going to repeat anything here. Hopefully a fully working example will expedite your own development efforts.</p>  <p>· The full source for the fonts and color provider can be downloaded <a href="https://cid-9743d44f2931a23d.skydrive.live.com/self.aspx/Blogs/SamplePackageFontAndColorProvider.zip">here</a>.</p>  <p>-- Patrick</p>]]></content:encoded>
    </item>
    <item>
      <title>Template Driven Sql Generation</title>
      <link>https://docs.microsoft.com/archive/blogs/psirr/template-driven-sql-generation</link>
      <pubDate>Fri, 31 Jul 2009 08:55:37 GMT</pubDate>
      <dc:creator><![CDATA[psirr-MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/psirr/2009/07/31/template-driven-sql-generation/</guid>
      <description><![CDATA[Recently Duke Kamstra and I demonstrated how you can use Visual Studio 2008 Database and Server...]]></description>
      <content:encoded><![CDATA[<p>Recently Duke Kamstra and I demonstrated how you can use Visual Studio 2008 Database and Server projects to deploy Sql Server permission objects to your various Sql Server instances. It’s common to develop on a local box with admin rights, and then restrict those rights as you start deploying to test, pre-production and, eventually, your production Sql Server instance. Database projects assume your schema model is static – an assumption that may work for Tables, Views and Sprocs, but not so much for Logins. In this blog I’ll show you three ways to manage SQL security principles changing as a schema is deployed to different staging environments: Pre-Build Events, Post-Deployment scripts and Visual Studio Extensibility.</p>  <h4>Pre-Build Events</h4>  <p>With this mechanism you’re swapping in new source files prior to each build. In the sample solution below I have two Visual Studio Configurations – ‘Sandbox’ and ‘Integration’. For each security object I’ve created 2 new files and navigated to the Properties Window to change their Build Action to ‘Not in Build’.</p>  <p>The pre-build event action is found in the project properties ‘Build Events’ tab:</p>  <p>In the pre-build textbox I’ve inserted a script for swapping in new security objects just prior to the build.</p>  <div style="border-bottom: gray 1px solid; border-left: gray 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; max-height: 200px; font-size: 8pt; overflow: auto; border-top: gray 1px solid; cursor: text; border-right: gray 1px solid; padding-top: 4px">   <div style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">     <pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">   1:</span> <span style="color: #0000ff">if</span> [$(Configuration)] == [Integration] (</pre>

    <pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">   2:</span>     xcopy /r /y <span style="color: #006080">&quot;$(ProjectDir)User1.user.integration.sql&quot;</span> <span style="color: #006080">&quot;$(ProjectDir)User1.user.sql&quot;</span> </pre>

    <pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">   3:</span>     echo copied <span style="color: #006080">&quot;$(ProjectDir)User1.user.integration.sql&quot;</span> to <span style="color: #006080">&quot;$(ProjectDir)User1.user.sql&quot;</span> </pre>

    <pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">   4:</span> ) <span style="color: #0000ff">else</span> <span style="color: #0000ff">if</span> [$(Configuration)] == [Sandbox] (</pre>

    <pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">   5:</span>     xcopy /r /y <span style="color: #006080">&quot;$(ProjectDir)User1.user.sandbox.sql&quot;</span> <span style="color: #006080">&quot;$(ProjectDir)User1.user.sql&quot;</span> </pre>

    <pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">   6:</span>     echo copied <span style="color: #006080">&quot;$(ProjectDir)User1.user.integration.sql&quot;</span> to <span style="color: #006080">&quot;$(ProjectDir)User1.user.sql&quot;</span> </pre>

    <pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">   7:</span> ) <span style="color: #0000ff">else</span> (</pre>

    <pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">   8:</span>     del <span style="color: #006080">&quot;$(ProjectDir) User1.user.sql&quot;</span> </pre>

    <pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">   9:</span> )</pre>
  </div>
</div>

<p>Note that I’m using “xcopy /r” which overwrites the target file even if it’s marked readonly. I consider this a reasonable approach because, even if you do have this file in version control, it contains no useful information. The interesting, versionable information actually resides in the .sandbox.sql and .integrationl.sql files.</p>

<p>Advantages</p>

<ul>
  <li>Object references in the schema model will be validated during the build process </li>

  <li>Deploy will accurately compare the identifiers for security objects between the project and the target database </li>
</ul>

<p>Disadvantages</p>

<ul>
  <li>Refactoring the security object will not modify the definition in the configuration specific scripts. </li>

  <li>Schema Compare will compare the identifier defined in the script which is “In Build” to the target. This may result in unexpected differences. </li>

  <li>If you need to create a new Visual Studio configuration for each target SQL server you will be deploying to. </li>
</ul>

<h4>Post-Deployment File</h4>

<p>Another approach to creating security objects is to place all your security-based T-Sql in your Post-Deployment Script.</p>

<p>Here’s an example of a Post-Deployment script used in this way:</p>

<div style="border-bottom: gray 1px solid; border-left: gray 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; max-height: 200px; font-size: 8pt; overflow: auto; border-top: gray 1px solid; cursor: text; border-right: gray 1px solid; padding-top: 4px">
  <div style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
    <pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">   1:</span> <span style="color: #008000">/*</span></pre>

    <pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">   2:</span> <span style="color: #008000"></span></pre>

    <pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">   3:</span> <span style="color: #008000">Post-Deployment Script Template</span></pre>

    <pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">   4:</span> <span style="color: #008000"></span></pre>

    <pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">   5:</span> <span style="color: #008000">*/</span></pre>

    <pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">   6:</span>&#160; </pre>

    <pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">   7:</span> IF ((<span style="color: #006080">'$(DatabaseName)'</span>) = <span style="color: #006080">'TR9_Database_Dev'</span>)</pre>

    <pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">   8:</span> BEGIN</pre>

    <pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">   9:</span>     PRINT N<span style="color: #006080">'Creating Sandbox Security Objects...'</span>;</pre>

    <pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  10:</span>     IF NOT EXISTS (SELECT * FROM sys.server_principals WHERE name = N<span style="color: #006080">'TR9-DEV\TR9_CONTROL'</span>)</pre>

    <pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  11:</span>     BEGIN</pre>

    <pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  12:</span>         CREATE LOGIN [TR9-DEV\TR9_CONTROL] FROM WINDOWS;</pre>

    <pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  13:</span>         EXECUTE sp_addsrvrolemember @loginame = N<span style="color: #006080">'TR9-DEV\TR9_CONTROL'</span>, @rolename = N<span style="color: #006080">'dbcreator'</span>;</pre>

    <pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  14:</span>         IF NOT EXISTS (SELECT * FROM sys.database_principals WHERE name = N<span style="color: #006080">'TR9-DEV\TR9_CONTROL'</span>)</pre>

    <pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  15:</span>         BEGIN</pre>

    <pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  16:</span>             CREATE USER [TR9Control] FOR LOGIN [TR9-DEV\TR9_CONTROL];</pre>

    <pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  17:</span>             EXECUTE sp_addrolemember @rolename = N<span style="color: #006080">'TR9_Control'</span>, @membername = N<span style="color: #006080">'TR9Control'</span>;</pre>

    <pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  18:</span>         END</pre>

    <pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  19:</span>     END </pre>

    <pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  20:</span>     IF NOT EXISTS (SELECT * FROM sys.server_principals WHERE name = N<span style="color: #006080">'TR9-DEV\TR9_USERS'</span>)</pre>

    <pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  21:</span>     BEGIN</pre>

    <pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  22:</span>         CREATE LOGIN [TR9-DEV\TR9_USERS] FROM WINDOWS</pre>

    <pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  23:</span>         IF NOT EXISTS (SELECT * FROM sys.database_principals WHERE name = N<span style="color: #006080">'TR9-DEV\TR9_USERS'</span>)</pre>

    <pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  24:</span>         BEGIN</pre>

    <pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  25:</span>             CREATE USER [TR9Users] FOR LOGIN [TR9-DEV\TR9_USERS];</pre>

    <pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  26:</span>             EXECUTE sp_addrolemember @rolename = N<span style="color: #006080">'TR9_Users'</span>, @membername = N<span style="color: #006080">'TR9Control'</span>;</pre>

    <pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  27:</span>             EXECUTE sp_addrolemember @rolename = N<span style="color: #006080">'TR9_Users'</span>, @membername = N<span style="color: #006080">'TR9Users'</span>;</pre>

    <pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  28:</span>         END</pre>

    <pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  29:</span>     END </pre>

    <pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  30:</span> END</pre>

    <pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  31:</span> ELSE</pre>

    <pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  32:</span> BEGIN</pre>

    <pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  33:</span>     PRINT N<span style="color: #006080">'Creating Integration Security Objects...'</span></pre>

    <pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  34:</span>     IF NOT EXISTS (SELECT * FROM sys.server_principals WHERE name = N<span style="color: #006080">'TR9-INT\TR9_CONTROL'</span>)</pre>

    <pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  35:</span>     BEGIN</pre>

    <pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  36:</span>         CREATE LOGIN [TR9-INT\TR9_CONTROL] FROM WINDOWS;</pre>

    <pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  37:</span>         EXECUTE sp_addsrvrolemember @loginame = N<span style="color: #006080">'TR9-INT\TR9_CONTROL'</span>, @rolename = N<span style="color: #006080">'dbcreator'</span>;</pre>

    <pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  38:</span>         IF NOT EXISTS (SELECT * FROM sys.database_principals WHERE name = N<span style="color: #006080">'TR9-INT\TR9_CONTROL'</span>)</pre>

    <pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  39:</span>         BEGIN</pre>

    <pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  40:</span>             CREATE USER [TR9Control] FOR LOGIN [TR9-INT\TR9_CONTROL];</pre>

    <pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  41:</span>             EXECUTE sp_addrolemember @rolename = N<span style="color: #006080">'TR9_Control'</span>, @membername = N<span style="color: #006080">'TR9Control'</span>;</pre>

    <pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  42:</span>         END</pre>

    <pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  43:</span>     END </pre>

    <pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  44:</span>     IF NOT EXISTS (SELECT * FROM sys.server_principals WHERE name = N<span style="color: #006080">'TR9-INT\TR9_USERS'</span>)</pre>

    <pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  45:</span>     BEGIN</pre>

    <pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  46:</span>         CREATE LOGIN [TR9-INT\TR9_USERS] FROM WINDOWS</pre>

    <pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  47:</span>         IF NOT EXISTS (SELECT * FROM sys.database_principals WHERE name = N<span style="color: #006080">'TR9-INT\TR9_USERS'</span>)</pre>

    <pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  48:</span>         BEGIN</pre>

    <pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  49:</span>             CREATE USER [TR9Users] FOR LOGIN [TR9-INT\TR9_USERS];</pre>

    <pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  50:</span>         EXECUTE sp_addrolemember @rolename = N<span style="color: #006080">'TR9_Users'</span>, @membername = N<span style="color: #006080">'TR9Control'</span>;</pre>

    <pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  51:</span>         EXECUTE sp_addrolemember @rolename = N<span style="color: #006080">'TR9_Users'</span>, @membername = N<span style="color: #006080">'TR9Users'</span>;</pre>

    <pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  52:</span>         END</pre>

    <pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  53:</span>     END </pre>

    <pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  54:</span> END</pre>
  </div>
</div>

<p>Once again, since the objects do not exist as part of the project system model they cannot participate in the schema differencing process which occurs prior to deployment. Any errors in the objects or your script will not appear until you deploy.</p>

<p>Advantages</p>

<ul>
  <li>All of your security objects are defined in one script. </li>
</ul>

<p>Disadvantages</p>

<ul>
  <li>Since the security objects are not defined in the database schema they will not participate in Refactoring or Schema Compare. </li>

  <li>You may need conditional in the script for each target SQL server you will be deploying to.&#160; If your security objects are similar enough you may be able to use SqlCmd variables to instead of the IF/ELSE scheme I used. </li>
</ul>

<h4>Visual Studio Extensibility</h4>

<p>Now I’ll introduce you to the Visual Studio Add-In ProcessSqlTemplateAddIn and associated MSBuild Task. These components use Visual Studio Extensibility to pre-process your T-Sql scripts and bind the value of SQLCMD variables to the respective values defined in the active project configuration. When you select a project configuration the MSBuild task scans the project for template script files. Any variables that are discovered in the templates are replaced with the respective value.</p>

<p>Install the Add-In and MSBuild Task using <a href="https://cid-9743d44f2931a23d.skydrive.live.com/self.aspx/Blogs/InstallProcessSqlTemplate.msi">this</a> msi. The MSI will install the following components:</p>

<ul>
  <li>%ProgramFiles%MSBuild\Microsoft\VisualStudio\v9.0\TeamData\ProcessSqlTemplate.Task.Targets </li>

  <li>%ProgramFiles%Microsoft Visual Studio 9.0\Common7\IDE\PublicAssemblies\ProcessSqlTemplateAddIn.dll </li>

  <li>%ProgramFiles%Microsoft Visual Studio 9.0\VSTSDB\ProcessSqlTemplate.Task.dll </li>

  <li>%ProgramData%\Microsoft\MSEnvShared\Addins\ProcessSqlTemplateAddIn.AddIn </li>
</ul>

<p>After installing, create a Server Project and in that project create a file called ‘Login1.login.template.sql’. The “template.sql” at the end of the filename indicates to the Add-In that this is a template script. Copy the following text to that file:</p>

<div style="border-bottom: gray 1px solid; border-left: gray 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; max-height: 200px; font-size: 8pt; overflow: auto; border-top: gray 1px solid; cursor: text; border-right: gray 1px solid; padding-top: 4px">
  <div style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
    <pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">   1:</span> --*CREATE LOGIN [$(SVR)\TR9_CONTROL] FROM WINDOWS</pre>

    <pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">   2:</span> --*GO</pre>

    <pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">   3:</span> --*CREATE LOGIN [$(SVR)\TR9_USERS] FROM WINDOWS</pre>
  </div>
</div>

<p></p>

<p>The “--*” indicates that this text is part of the template.</p>

<p>Next edit your project properties to create two new .sqlcmdvars file – one for your Sandbox and one for your Integration configuration. In the Sandbox .sqlcmdvars file define $(SVR) as “SVR-DEV”. In your integration .sqlcmdvars file define $(SVR) as “SVR-INT”.</p>

<p>Now we need to chain our new MSBuild task into the build process. As part of the ProcessSqlTemplateAddIn MSI a targets file was installed. This target file contains the definition of the ProcessSqlTemplate MSBuild task. Unload the project and insert the following Import statement into your project file after the ‘Microsoft.Data.Schema.SqlTasks.targets’ import statement:</p>

<p>&lt;Import Project=&quot;$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v9.0\TeamData\ProcessSqlTemplate.Task.Targets&quot; /&gt;</p>

<p>Reload the project and you’ll see that switching configurations will alter the contents of your ‘Login1.login.template.sql’ script according to the value of your sqlcmdvars for that configuration. A sample project is included <a href="https://cid-9743d44f2931a23d.skydrive.live.com/self.aspx/Blogs/Sample3SqlTemplate.zip">here</a>.</p>

<p>Before I leave this top there’s one advantage I’d like to explain. Because this approach is bound to your configurations SqlCmd variables file you are able to provide these variable values on the MSBuild commandline. To do this create a new ItemGroup in your project file with the name of the SqlCmd variable you may want to override:</p>

<div style="border-bottom: gray 1px solid; border-left: gray 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; max-height: 200px; font-size: 8pt; overflow: auto; border-top: gray 1px solid; cursor: text; border-right: gray 1px solid; padding-top: 4px">
  <div style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
    <pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">   1:</span> &lt;ItemGroup&gt;</pre>

    <pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">   2:</span>     &lt;SqlCommandVariableOverride Include=<span style="color: #006080">&quot;SVR=$(SVR)&quot;</span> Condition=<span style="color: #006080">&quot;'$(SVR)' != ''&quot;</span>/&gt;</pre>

    <pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">   3:</span> &lt;/ItemGroup&gt;</pre>
  </div>
</div>

<p></p>

<p>With this ItemGroup in place I can now execute MSBuild supplying the configuration as well as an override for the $(SVR) sqlcmd variable. There’s a good forum post on this topic <a href="https://social.msdn.microsoft.com/Forums/en-US/vstsdb/thread/0033e77f-665e-4bda-ba5a-57e34e45c05a">here</a>.</p>

<p>msbuild /t:rebuild /property:Configuration=Sandbox;SVR=Patrick TR9_Database\TR9_Database.sln</p>

<p>Advantages</p>

<ul>
  <li>The database developer only needs to implement one SQL script defining the security object. </li>

  <li>The identifier for the security object is represented as a variable that is bound to the correct value when the project is built. </li>

  <li>Deploy will correctly compare the project’s schema definition with the target database. </li>

  <li>It makes use of SqlCmd variables which are overridable on the command line. </li>
</ul>

<p>Disadvantages</p>

<ul>
  <li>The Add-In and MSBuild task need to be installed on each Developer’s computer as well as the TFS Build server. </li>

  <li>The .dbproj file must be modified to include the MSBuild target. </li>

  <li>Refactoring will not modify the schema template definitions. </li>
</ul>

<h4>Visual Studio Extensibility Source Code</h4>

<p>The source code for the Add-in, MSBuild task and the installer is located <a href="https://cid-9743d44f2931a23d.skydrive.live.com/self.aspx/Blogs/ProcessSqlTemplateAddIn.zip">here</a>. To compile this you’ll need Visual Studio 2008, the <a href="https://www.microsoft.com/downloads/details.aspx?FamilyID=30402623-93ca-479a-867c-04dc45164f5b&amp;DisplayLang=en">Visual Studio 2008 VSSDK</a>, and <a href="https://wix.sourceforge.net/votive.html">Votive</a> 3.0 (I used 3.0.4707.0).</p>

<p>The MSBuild addin is located in the ProcessSqlTemplateAddIn project. Visit the source file Connect.impl.cs for the most interesting details of the implemention. Note that Connect implements IVsUpdateSolutionEvents and IVsSolutionEvents. These events help the addin listen to database projects opening/closing as well as when their configuration changes. When a configuration does change ProcessAllTemplates is called which calls on the MSBuild task to do the template processing.</p>

<p>The MSBuild task is located in the ProcessSqlTemplate.Task project. Take a look at ProcessSqlTemplateTask.Execute for its entry method.</p>

<h4>Conclusion</h4>

<p>In this blog we’ve discussed three possibilities for deploying server objects to different Sql Server instances from a single Visual Studio Solution. To install the msi or view the source code you’ll need Visual Studio Team System 2008 Database Edition GDR.</p>

<p>The source code for the Visual Studio ProcessSqlTemplate MSBuild Task and Add-in is <a href="https://cid-9743d44f2931a23d.skydrive.live.com/self.aspx/Blogs/InstallProcessSqlTemplate.zip">here</a>.</p>

<p>The sample project demonstrating how to use the Add-In is <a href="https://cid-9743d44f2931a23d.skydrive.live.com/self.aspx/Blogs/Sample3SqlTemplate.zip">here</a>.</p>

<p>The ProcessSqlTemplateAddIn MSI is located <a href="https://cid-9743d44f2931a23d.skydrive.live.com/self.aspx/Blogs/InstallProcessSqlTemplate.msi">here</a>.<del datetime="2009-07-28T12:34" cite="mailto:Duke%20Kamstra"></del></p>]]></content:encoded>
    </item>
    <item>
      <title>Using T4 Templates with GDR Database Projects</title>
      <link>https://docs.microsoft.com/archive/blogs/psirr/using-t4-templates-with-gdr-database-projects</link>
      <pubDate>Mon, 29 Dec 2008 14:59:44 GMT</pubDate>
      <dc:creator><![CDATA[psirr-MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/psirr/2008/12/29/using-t4-templates-with-gdr-database-projects/</guid>
      <description><![CDATA[For this blog I’ve developed an add-in for General Distribution Release (GDR) for Visual Studio Team...]]></description>
      <content:encoded><![CDATA[<p>For this blog I’ve developed an add-in for General Distribution Release (GDR) for Visual Studio Team System 2008 Database Edition projects (better known as “Data Dude”) which will generate Create, Read, Update and Delete (CRUD) stored procedures for a particular table in your model.&#160; I wanted to provide the ability to affect the content of those procedures without recompiling my add-in so I’m using Visual Studio’s built in, template based, code generation tool - known as T4.&#160; It’s not well known but extremely powerful.&#160; There’s a good MSDN article <a href="https://msdn.microsoft.com/en-us/library/bb126445.aspx">here</a>. I’ll go through the key pieces of the code, but there’s nothing like running it for yourself, so I’ve provided the entire source in this <a href="https://cid-9743d44f2931a23d.skydrive.live.com/self.aspx/Blogs/CRUDGenerator.zip">zip</a>.</p>  <h4>Overview of the Add-In</h4>  <p>The zip reference above contains an MSI called InstallCRUDGenerator.msi. Once you install, make sure the add-in is loaded by selecting the “Tools.Add-in Manager” menu button:</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/psirr/WindowsLiveWriter/UsingT4TemplateswithGDRDatabaseProjects_A8A8/clip_image002_2.jpg" original-url="https://blogs.msdn.com/blogfiles/psirr/WindowsLiveWriter/UsingT4TemplateswithGDRDatabaseProjects_A8A8/clip_image002_2.jpg"><img title="clip_image002" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="329" alt="clip_image002" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/psirr/WindowsLiveWriter/UsingT4TemplateswithGDRDatabaseProjects_A8A8/clip_image002_thumb.jpg" original-url="https://blogs.msdn.com/blogfiles/psirr/WindowsLiveWriter/UsingT4TemplateswithGDRDatabaseProjects_A8A8/clip_image002_thumb.jpg" width="510" border="0" /></a></p>  <p>Once loaded any scripts containing tables will display a “CRUDGenerator” button in your Solution Explorer context menu:</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/psirr/WindowsLiveWriter/UsingT4TemplateswithGDRDatabaseProjects_A8A8/clip_image004_2.jpg" original-url="https://blogs.msdn.com/blogfiles/psirr/WindowsLiveWriter/UsingT4TemplateswithGDRDatabaseProjects_A8A8/clip_image004_2.jpg"><img title="clip_image004" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="303" alt="clip_image004" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/psirr/WindowsLiveWriter/UsingT4TemplateswithGDRDatabaseProjects_A8A8/clip_image004_thumb.jpg" original-url="https://blogs.msdn.com/blogfiles/psirr/WindowsLiveWriter/UsingT4TemplateswithGDRDatabaseProjects_A8A8/clip_image004_thumb.jpg" width="330" border="0" /></a></p>  <p>If you select this the CRUD Generation Dialog will appear:</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/psirr/WindowsLiveWriter/UsingT4TemplateswithGDRDatabaseProjects_A8A8/clip_image006_2.jpg" original-url="https://blogs.msdn.com/blogfiles/psirr/WindowsLiveWriter/UsingT4TemplateswithGDRDatabaseProjects_A8A8/clip_image006_2.jpg"><img title="clip_image006" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="283" alt="clip_image006" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/psirr/WindowsLiveWriter/UsingT4TemplateswithGDRDatabaseProjects_A8A8/clip_image006_thumb.jpg" original-url="https://blogs.msdn.com/blogfiles/psirr/WindowsLiveWriter/UsingT4TemplateswithGDRDatabaseProjects_A8A8/clip_image006_thumb.jpg" width="523" border="0" /></a></p>  <p>This dialog allows you to select your source table script and then view the generated CRUD stored procedures. If you’re happy with the generated procedures select “Save Procedures to Project” and 4 new stored procedures will be created in your project.</p>  <p>Now for the details! The text box in the middle of the CRUD Generation Dialog contains your T4 template. At the start of this blog I gave you a good T4 link so I won’t go into details on the scripting language itself, but let’s adjust the Create procedure seen in the image above. First let’s add my company name to the comments for this stored procedure. The comment is generated on lines 10 through 13 of the T4 Template:</p>  <div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, &#39;Courier New&#39;, courier, monospace; height: 117px; background-color: #f4f4f4">   <div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">     <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   1:</span> <span style="color: #008000">/*</span></pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   2:</span> <span style="color: #008000">CREATE procedure for &lt;#= tableFullName #&gt;</span></pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   3:</span> <span style="color: #008000">Generated &lt;#= DateTime.Now.ToString() #&gt;</span></pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   4:</span> <span style="color: #008000">*/</span></pre>
  </div>
</div>

<p></p>

<p>Let’s change this to </p>

<div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, &#39;Courier New&#39;, courier, monospace; height: 136px; background-color: #f4f4f4">
  <div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   1:</span> <span style="color: #008000">/*</span></pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   2:</span> <span style="color: #008000">Copyright (c) Microsoft Corporation. All rights reserved.</span></pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   3:</span> <span style="color: #008000">CREATE procedure for &lt;#= tableFullName #&gt;</span></pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   4:</span> <span style="color: #008000">Generated &lt;#= DateTime.Now.ToString() #&gt;</span></pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   5:</span> <span style="color: #008000">*/</span></pre>
  </div>
</div>

<p></p>

<p>.. and hit the “Generate” button:</p>

<p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/psirr/WindowsLiveWriter/UsingT4TemplateswithGDRDatabaseProjects_A8A8/clip_image008_2.jpg" original-url="https://blogs.msdn.com/blogfiles/psirr/WindowsLiveWriter/UsingT4TemplateswithGDRDatabaseProjects_A8A8/clip_image008_2.jpg"><img title="clip_image008" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="286" alt="clip_image008" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/psirr/WindowsLiveWriter/UsingT4TemplateswithGDRDatabaseProjects_A8A8/clip_image008_thumb.jpg" original-url="https://blogs.msdn.com/blogfiles/psirr/WindowsLiveWriter/UsingT4TemplateswithGDRDatabaseProjects_A8A8/clip_image008_thumb.jpg" width="533" border="0" /></a></p>

<p>Notice now that our copyright appears in the generated stored procedure T-SQL and we did this without modifying our add-in. Very cool!</p>

<p>Feel free to experiment and modify the T4 templates I provide in this add-in. There are 5 templates installed into “%ProgramFiles%\Microsoft Visual Studio 9.0 CRUD Template AddIn”:</p>

<p>· CrudCreate.tt</p>

<blockquote>
  <p>o Responsible for generated the ‘Create’ stored procedure</p>
</blockquote>

<p>· CrudDelete.tt </p>

<blockquote>
  <p>o Responsible for generated the ‘Delete’ stored procedure</p>
</blockquote>

<p>· CrudRead.tt </p>

<blockquote>
  <p>o Responsible for generated the ‘Read’ stored procedure</p>
</blockquote>

<p>· CrudUpdate.tt </p>

<blockquote>
  <p>o Responsible for generated the ‘Update’ stored procedure</p>
</blockquote>

<p>· CrudToolbox.tt</p>

<blockquote>
  <p>o Useful utilities for walking the Data Dude model. This is where the columns are analyzed to determine how they are used in the templates above.</p>
</blockquote>

<p>CrudToolbox.tt contains the most code. It’s here where I walk the Data Dude object model to determine the column and column types for the selected table. If you wish to change this file remember that it too can be altered without having to restart Visual Studio. Just open it in a text editor or another Visual Studio instance, edit and then hit the ‘Generate’ button as we did before.</p>

<h4>Overview of the Add-In Code</h4>

<p>In this section I’ll provide you with an overview of the CRUD Generator Add-in code. For anyone that’s ever generated a Visual Studio Add-in project you’ll know that Connect.cs is where the add-in initializes. It’s there where I add the ‘CRUD Generator’ button to the Solution Explorer context menu and handle the button click. My handling is a simple pass-off to a class I call the CRUDEngine:</p>

<div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.39%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, &#39;Courier New&#39;, courier, monospace; height: 226px; background-color: #f4f4f4">
  <div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   1:</span> <span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> Exec(<span style="color: #0000ff">string</span> commandName, vsCommandExecOption executeOption, <span style="color: #0000ff">ref</span> <span style="color: #0000ff">object</span> varIn, <span style="color: #0000ff">ref</span> <span style="color: #0000ff">object</span> varOut, <span style="color: #0000ff">ref</span> <span style="color: #0000ff">bool</span> handled)</pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   2:</span> {</pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   3:</span>     handled = <span style="color: #0000ff">false</span>;</pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   4:</span>     <span style="color: #0000ff">if</span>(executeOption == vsCommandExecOption.vsCommandExecOptionDoDefault)</pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   5:</span>     {</pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   6:</span>         <span style="color: #0000ff">if</span>(commandName == <span style="color: #006080">&quot;CRUDGenerator.Connect.CRUDGenerator&quot;</span>)</pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   7:</span>         {</pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   8:</span>             CRUDEngine engine = <span style="color: #0000ff">new</span> CRUDEngine(ProjectFinder.GetFirstDatabaseProject(_applicationObject));</pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   9:</span>             engine.Run();</pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  10:</span>             handled = <span style="color: #0000ff">true</span>;</pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  11:</span>             <span style="color: #0000ff">return</span>;</pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  12:</span>         }</pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  13:</span>     }</pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  14:</span> }</pre>
  </div>
</div>

<p></p>

<p>This engine creates an instance of my WinForms dialog and provides that dialog with a class I call the CRUDGenerator:</p>

<div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, &#39;Courier New&#39;, courier, monospace; height: 147px; background-color: #f4f4f4">
  <div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   1:</span> <span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> Run()</pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   2:</span> {</pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   3:</span>     CRUDDialog dialog = <span style="color: #0000ff">new</span> CRUDDialog();</pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   4:</span>     dialog.Generator = <span style="color: #0000ff">new</span> CRUDGenerator(_project);</pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   5:</span>     dialog.ShowDialog();</pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   6:</span> }</pre>
  </div>
</div>

<p></p>

<p>I won’t go over my CRUDDialog since most of it is simple WinForms programming. The CRUDGenerator is where we’ll focus next. This class is responsible for executing the T4 scripting engine and returning the results. For more information on executing T4 programmatically see <a href="https://msdn.microsoft.com/en-us/library/bb126579.aspx">this msdn page</a>.</p>

<p>The most important thing to note when walking the Data Dude object model is that it is not Serializable (although it is thread-safe). This means you cannot access the object model from another process (i.e. through out of process DTE) or from another AppDomain. Fortunately during the process of executing the T4 template engine you have the opportunity to provide a class which must derive from ITextTemplatingEngineHost. My instance of that host is called VSDBCustomHost and it it I provide the current AppDomain</p>

<div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, &#39;Courier New&#39;, courier, monospace; height: 121px; background-color: #f4f4f4">
  <div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   1:</span> <span style="color: #0000ff">public</span> AppDomain ProvideTemplatingAppDomain(<span style="color: #0000ff">string</span> content)</pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   2:</span> {</pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   3:</span>     <span style="color: #0000ff">return</span> AppDomain.CurrentDomain;</pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   4:</span> }</pre>
  </div>
</div>

<p></p>

<p>The core of this class is it’s RunTemplate method. In that method I create an instance of a VSDBCustomHost and process the template:</p>

<div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, &#39;Courier New&#39;, courier, monospace; height: 230px; background-color: #f4f4f4">
  <div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   1:</span> <span style="color: #0000ff">public</span> <span style="color: #0000ff">string</span> RunTemplate(ISqlTable selectedTable, </pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   2:</span>                         <span style="color: #0000ff">string</span> templateFullPath,</pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   3:</span>                         <span style="color: #0000ff">out</span> CompilerErrorCollection errors)</pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   4:</span> {</pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   5:</span>     <span style="color: #0000ff">string</span> tableScript = GetTableText(selectedTable);</pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   6:</span>     errors = <span style="color: #0000ff">null</span>;</pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   7:</span>     <span style="color: #0000ff">if</span> (<span style="color: #0000ff">string</span>.IsNullOrEmpty(templateFullPath))</pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   8:</span>         <span style="color: #0000ff">return</span> <span style="color: #0000ff">string</span>.Empty;</pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   9:</span>&#160; </pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  10:</span>     VSDBCustomHost host = <span style="color: #0000ff">new</span> VSDBCustomHost();</pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  11:</span>     Microsoft.VisualStudio.TextTemplating.Engine engine = <span style="color: #0000ff">new</span> Microsoft.VisualStudio.TextTemplating.Engine();</pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  12:</span>     host.TemplateFile = templateFullPath;</pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  13:</span>     host.IncludePath = Path.Combine(VsUtils.GetVSTSDBDirectory(), <span style="color: #006080">@&quot;Extensions\SqlServer\&quot;);</pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  14:</span>     host.VsUtils = _vsUtils;</pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  15:</span>     AppDomain domain = host.ProvideTemplatingAppDomain(string.Empty);</pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  16:</span>     string output = string.Empty;</pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  17:</span>     try</pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  18:</span>     {</pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  19:</span>         // Set the table to be generated into the app domain</pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  20:</span>         domain.SetData(&quot;</span>TT_TABLE<span style="color: #006080">&quot;, selectedTable);</pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  21:</span>         //Read the text template.</pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  22:</span>         string input = File.ReadAllText(templateFullPath);</pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  23:</span>         //Transform the text template.</pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  24:</span>         output = engine.ProcessTemplate(input, host);</pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  25:</span>         errors = host.Errors;</pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  26:</span>     }</pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  27:</span>     finally</pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  28:</span>     {</pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  29:</span>         domain.SetData(&quot;</span>TT_TABLE&quot;, <span style="color: #0000ff">null</span>);</pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  30:</span>     }</pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  31:</span>     <span style="color: #0000ff">return</span> output;</pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  32:</span> }</pre>
  </div>
</div>

<p>At the beginning of this blog is the link to the zip file containing all the source for this add-in. From here I’ll leave you to paruse the source.</p>

<h4>Conclusion</h4>

<p>Hopefully you’ve now got an appreciation of the power of T4 templates! Remember that if you want to use these templates with Data Dude projects you’ll have to provide your own templating engine host since the Data Dude model cannot cross process or AppDomain boundaries since it is not serializable. Feel free to ping me if you’ve got questions!&#160; Have a good 2009!</p>

<p>&#160;</p>

<p>Patrick Sirr</p>

<p>Data Dude Programmer </p>]]></content:encoded>
    </item>
    <item>
      <title>Navigating the Data Dude Object Model</title>
      <link>https://docs.microsoft.com/archive/blogs/psirr/navigating-the-data-dude-object-model</link>
      <pubDate>Thu, 11 Dec 2008 11:57:26 GMT</pubDate>
      <dc:creator><![CDATA[psirr-MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/psirr/2008/12/11/navigating-the-data-dude-object-model/</guid>
      <description><![CDATA[In this blog I’ll introduce you to the basics of navigating the General Distribution Release (GDR)...]]></description>
      <content:encoded><![CDATA[<p>In this blog I’ll introduce you to the basics of navigating the General Distribution Release (GDR) for Visual Studio Team System 2008 Database Edition object model. I’ve wrapped it all into an add-in so you can step through the code and extend it as you wish. I hope you find it useful! The first part of this blog will describe the basics for navigating the model. After we’ve covered that ground I’ll introduce you to the add-in.</p>  <h4>Basic Navigation</h4>  <p>I’m assuming you are writing an add-in. If so then your add-in will be initialized with a DTE2 object in its OnConnection method. This provides you with all the open projects in your solution. To find the database projects loop over all projects finding those with a EnvDTE.Project.Kind of “C8D11400-126E-41CD-887F-60BD40844F9E”.</p>  <p>Now that you’ve identified the <a href="https://msdn.microsoft.com/en-us/library/envdte.project.aspx">EnvDTE.Project</a> instance you can gain access to the DataDude model through the properties collection of this project. Get the “DataSchemaModel” property and cast to a Microsoft.Data.Schema.SchemaModel.DataSchemaModel. Note that you’ll need to add references to the DataDude assemblies Microsoft.Data.Schema.dll and Microsoft.Data.Schema.Sql.dll.</p>  <div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, &#39;Courier New&#39;, courier, monospace; background-color: #f4f4f4">   <div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">     <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   1:</span> <span style="color: #0000ff">public</span> <span style="color: #0000ff">static</span> DataSchemaModel GetModel(EnvDTE.Project project)</pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   2:</span> {</pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   3:</span>     <span style="color: #0000ff">object</span> obj = project.Properties.Item(<span style="color: #006080">&quot;DataSchemaModel&quot;</span>);</pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   4:</span>     <span style="color: #0000ff">return</span> ((EnvDTE.Property)obj).Value <span style="color: #0000ff">as</span> DataSchemaModel;</pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   5:</span> }</pre>
  </div>
</div>

<p></p>

<p>Note that the <a href="https://msdn.microsoft.com/en-us/library/microsoft.data.schema.schemamodel.dataschemamodel_members.aspx">DataSchemaModel</a> is thread-safe but is not XmlSerializable. So if you’re using DTE from an external process the DataSchemaModel property will return null.</p>

<p>Let’s continue and query the model for all the tables. Use the member <a href="https://msdn.microsoft.com/en-us/library/microsoft.data.schema.schemamodel.dataschemamodel.getelements.aspx">DataSchemaModel.GetElements</a> querying for <a href="https://msdn.microsoft.com/en-us/library/microsoft.data.schema.sql.schemamodel.sqlserver.isql90table.aspx">ISqlTable</a>. Note that we are choosing to use ElementQueryFilter.Internal as the argument because we only want those tables which have been defined by the user – not those brought in through an external reference to a .dbschema file. Here’s an example of how to retrieve all the tables in the project:</p>

<div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, &#39;Courier New&#39;, courier, monospace; background-color: #f4f4f4">
  <div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   1:</span> <span style="color: #0000ff">public</span> <span style="color: #0000ff">static</span> IList&lt;ISqlTable&gt; GetTables(DataSchemaModel model)</pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   2:</span> {</pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   3:</span>     <span style="color: #0000ff">return</span> model.GetElements&lt; ISqlTable &gt;(ElementQueryFilter.Internal); </pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   4:</span> }</pre>
  </div>
</div>

<p></p>

<p>Great! Now we have all the tables. Note that the objects returned by this query support other interfaces. For instance, ISqlTable supports <a href="https://msdn.microsoft.com/en-us/library/microsoft.data.schema.sql.schemamodel.sqlserver.isqlcolumnsource.aspx">ISqlColumnSource</a> which makes navigating the table columns much easier.</p>

<p>Even though you have access to the model changes to it are prohibited and will throw an exception. This is because the project system’s model is controled through scripts. It is only through these scripts that the model can be modified. Ok, so the next logical question is – “where is this table defined? What script? Where in that script?” Good question! Cast your object (i.e. the ISqlTable instance) to <a href="https://msdn.microsoft.com/en-us/library/microsoft.data.schema.schemamodel.iscriptsourcedelement.aspx">IScriptSourcedElement</a>. If this interface returns an <a href="https://msdn.microsoft.com/en-us/library/microsoft.data.schema.schemamodel.iscriptsourcedelement.elementsource.aspx">ElementSource</a> then it does indeed live in a source file in the project system. The CacheIdentifier field will be the full path filename in the project system and and the length/offset the location, within that file, of this particular object. Note also, that IScriptSourcedElement gives you access to the <a href="https://msdn.microsoft.com/en-us/library/microsoft.data.schema.schemamodel.elementsource.scriptdom.aspx">ScriptDom</a> allowing you to walk the ASTs if your needs include walking our parse tree. If you download the add-in source below and look at VsUtils.GetSelectedModelElements you’ll see where I use the ElementSource.</p>

<h4>Add-In Example</h4>

<p>Now I’ll introduce you to a General Distribution Release (GDR) for Visual Studio Team System 2008 Database Edition Add-in which will alter the script in your project to comment out selected schema-owned elements. I’ve included the source code but, in order to compile the install project you’ll need to install <a href="https://wix.sourceforge.net/votive.html">Votive</a> 3.0 (I used 3.0.4707.0). This add-in uses the DataSchemaModel features I talked about in the previous section.</p>

<p>To install run CommentOutAddIn.msi (available in <a href="https://cid-9743d44f2931a23d.skydrive.live.com/self.aspx/Blogs/CommentOutElementAddIn.zip">this</a> zip). This install will create these files on your filesystem:</p>

<p>%VSINSTALLDIR%\Common7\Ide\PublicAssemblies\VSTSDBCommentAddIn.dll</p>

<p>C:\ProgramData\Microsoft\MSEnvShared\Addins\CommentOutElementAddIn.AddIn</p>

<p>After installing run Visual Studio 2008 and bring up the Add-in Manager by selecting Tools.Add-in Manager from the main toolbar. Verify that “Database Project Comment Out Add-in” is available and selected to load. </p>

<p>A new menu will appear in the Data menu called “Comment Out…” whenever at least one Database Project is open in the solution explorer.</p>

<p>Selecting this menu button will bring up the Comment Out dialog. Select the Database Project to search and click the “Find Schema Objects” button. This will search the project for all Tables, Views and Procedures and populate the tree control you see in the image below. </p>

<p>At this point select the schema objects you’d like to comment out and select “Command Out Objects”. At this point the dialog will close and all the selected elements will be commented out from their respective files.</p>

<p>For each file you should see a message similar to this in the output window:</p>

<p>C:\TEMP\DATABASE3\DATABASE3\SCHEMA OBJECTS\SCHEMAS\SALES\TABLES\SPECIALOFFERPRODUCT.TABLE.SQL is being modified so selected schema objects may be commented out.</p>

<p>Here’s the result of the commenting out a table:</p>

<div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, &#39;Courier New&#39;, courier, monospace; background-color: #f4f4f4">
  <div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   1:</span> <span style="color: #008000">/*CREATE TABLE [Sales].[SpecialOfferProduct] (</span></pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   2:</span> <span style="color: #008000">    [SpecialOfferID] INT              NOT NULL,</span></pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   3:</span> <span style="color: #008000">    [ProductID]      INT              NOT NULL,</span></pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   4:</span> <span style="color: #008000">    [rowguid]        UNIQUEIDENTIFIER ROWGUIDCOL NOT NULL,</span></pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   5:</span> <span style="color: #008000">    [ModifiedDate]   DATETIME         NOT NULL</span></pre>

    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   6:</span> <span style="color: #008000">);*/</span></pre>
  </div>
</div>

<p></p>

<h4>Conclusion</h4>

<p>The Comment Out Add-in is capable of commenting out Tables, Views and Procs in your script. But more than that, I hope the source code provides some help to for those wishing to write add-ins to tailor to their specific needs. Enjoy!</p>

<p>- Patrick Sirr</p>

<p>“DataDude” Senior Programmer</p>]]></content:encoded>
    </item>
    <item>
      <title>Database Project Import Scripts Add In</title>
      <link>https://docs.microsoft.com/archive/blogs/psirr/database-project-import-scripts-add-in</link>
      <pubDate>Mon, 24 Nov 2008 12:30:32 GMT</pubDate>
      <dc:creator><![CDATA[psirr-MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/psirr/2008/11/24/database-project-import-scripts-add-in/</guid>
      <description><![CDATA[In this blog I’ll introduce you to the Import Scripts add-in to the General Distribution Release...]]></description>
      <content:encoded><![CDATA[<p>In this blog I’ll introduce you to the Import Scripts add-in to the General Distribution Release (GDR) for Visual Studio Team System 2008 Database Edition. With this add-in Visual Studio can import multiple scripts to populate a target database project. I’ve included the source code but, in order to compile the install project you’ll need to install <a href="https://wix.sourceforge.net/votive.html">Votive</a> 3.0 (I used 3.0.4707.0).</p>  <p>To install run InstallImportScripts.msi (available in <a href="https://cid-9743d44f2931a23d.skydrive.live.com/self.aspx/Blogs/ImportScriptsAddin.zip">this</a> zip). This install will create these files on your filesystem:</p>  <p>%VSINSTALLDIR%\Common7\Ide\PublicAssemblies\ImportScriptsRecursively.dll</p>  <p>C:\ProgramData\Microsoft\MSEnvShared\Addins\ImportScriptsRecursively.AddIn</p>  <p>After installing run Visual Studio 2008 and bring up the Add-in Manager by selecting Tools.Add-in Manager from the main toolbar. Verify that “Database Project Script Import” is available and selected to load. </p>  <p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/psirr/WindowsLiveWriter/DatabaseProjectImportScriptsAddIn_85AB/clip_image002_2.jpg" original-url="https://blogs.msdn.com/blogfiles/psirr/WindowsLiveWriter/DatabaseProjectImportScriptsAddIn_85AB/clip_image002_2.jpg"><img title="clip_image002" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="240" alt="clip_image002" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/psirr/WindowsLiveWriter/DatabaseProjectImportScriptsAddIn_85AB/clip_image002_thumb.jpg" original-url="https://blogs.msdn.com/blogfiles/psirr/WindowsLiveWriter/DatabaseProjectImportScriptsAddIn_85AB/clip_image002_thumb.jpg" width="372" border="0" /></a></p>  <p>A new menu will appear in the Data menu called “Import Scripts…” whenever at least one Database Project is open in the solution explorer.</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/psirr/WindowsLiveWriter/DatabaseProjectImportScriptsAddIn_85AB/clip_image004_2.jpg" original-url="https://blogs.msdn.com/blogfiles/psirr/WindowsLiveWriter/DatabaseProjectImportScriptsAddIn_85AB/clip_image004_2.jpg"><img title="clip_image004" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="212" alt="clip_image004" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/psirr/WindowsLiveWriter/DatabaseProjectImportScriptsAddIn_85AB/clip_image004_thumb.jpg" original-url="https://blogs.msdn.com/blogfiles/psirr/WindowsLiveWriter/DatabaseProjectImportScriptsAddIn_85AB/clip_image004_thumb.jpg" width="244" border="0" /></a></p>  <p>Selecting this menu button will bring up the Scripts Selector dialog. Use this dialog to</p>  <p>· Select the project which will receive the imported database schema objects (the target project)</p>  <p>· Select the directory to search for .sql files</p>  <p>· Select or deselect individual files or folders from the import process. Note that, by default any scripts named Script.PostDeployment.sql, Script.PreDeployment.sql or IgnoredOnImport.sql will not be selected.</p>  <p>· Select the default encoding for the .sql files. If you run the addin and no database schema objects are imported verify the encoding of your files match the encoding you’ve selected in the Scripts Selector dialog.</p>  <p>· Choose among the various import script options available on the Import Script Wizard.</p>  <p>· If you choose to concatenate your scripts into one large file memory pressure will increase but performance will be vastly increased.</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/psirr/WindowsLiveWriter/DatabaseProjectImportScriptsAddIn_85AB/clip_image006_2.jpg" original-url="https://blogs.msdn.com/blogfiles/psirr/WindowsLiveWriter/DatabaseProjectImportScriptsAddIn_85AB/clip_image006_2.jpg"><img title="clip_image006" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="472" alt="clip_image006" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/psirr/WindowsLiveWriter/DatabaseProjectImportScriptsAddIn_85AB/clip_image006_thumb.jpg" original-url="https://blogs.msdn.com/blogfiles/psirr/WindowsLiveWriter/DatabaseProjectImportScriptsAddIn_85AB/clip_image006_thumb.jpg" width="482" border="0" /></a></p>  <p>Once you select ‘Run Import’ the Output Window will be activated and messages will appear providing you with feedback on the import script process. Each file will produce output similar to the one below. The output will include 1) a progress indicator (in the case below 4/700) and 2) the DTE command which can be executed into the Command Window to re-import that particular script (in the case below Project.ImportScript /FileName &quot;C:\temp\AdventureWorks\AdventureWorks\Schema Objects\Database Level Objects\Security\Schemas\Person.schema.sql&quot; /Encoding UTF8).    <table cellspacing="0" cellpadding="0" border="1"><tbody>       <tr>         <td valign="top" width="638">           <p>Executing 4/700 : Project.ImportScript /FileName &quot;C:\temp\AdventureWorks\AdventureWorks\Schema Objects\Database Level Objects\Security\Schemas\Person.schema.sql&quot; /Encoding UTF8 </p>            <p>Started importing file: C:\temp\AdventureWorks\AdventureWorks\Schema Objects\Database Level Objects\Security\Schemas\Person.schema.sql </p>            <p>File name C:\temp\AdventureWorks\AdventureWorks\Schema Objects\Database Level Objects\Security\Schemas\Person.schema.sql (size: 270)</p>            <p>Parsing SQL script</p>            <p>Total number of batches in script: 2</p>            <p>Total number of statements in script: 2</p>            <p>Finished importing file: C:\temp\AdventureWorks\AdventureWorks\Schema Objects\Database Level Objects\Security\Schemas\Person.schema.sql</p>         </td>       </tr>     </tbody></table> </p>  <h3>Conclusion</h3>  <p>The Import Scripts Add-in allows you to import multiple scripts at once. This should be a useful addin when upgrading from CTPs (which do not support upgrade) or importing from a script archive into a database project for the first time. </p>  <p>- Patrick Sirr</p>  <p>- DataDude Programmer</p>]]></content:encoded>
    </item>
  </channel>
</rss>