<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:copyright="http://blogs.law.harvard.edu/tech/rss" xmlns:image="http://purl.org/rss/1.0/modules/image/" version="2.0">
    <channel>
        <title>Anastasiosyal.com</title>
        <link>http://anastasiosyal.com/Default.aspx</link>
        <description>So what's the buzzword today!?</description>
        <language>en</language>
        <copyright>Anastasios Yalanopoulos</copyright>
        <generator>Subtext Version 2.1.0.5</generator>
        <image>
            <title>Anastasiosyal.com</title>
            <url>http://anastasiosyal.com/images/RSS2Image.gif</url>
            <link>http://anastasiosyal.com/Default.aspx</link>
            <width>77</width>
            <height>60</height>
        </image>
        <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/anastasiosyal" type="application/rss+xml" /><item>
            <title>Beyond SoundEx - Functions for Fuzzy Searching in MS SQL Server</title>
            <category>C#</category>
            <category>SQL</category>
            <category>SQLCLR</category>
            <link>http://anastasiosyal.com/archive/2009/01/11/18.aspx</link>
            <description>&lt;p&gt;In this post:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;&lt;a href="#soundex"&gt;SoundEx in Sql Server&lt;/a&gt;  &lt;/li&gt;&lt;li&gt;&lt;a href="#simmetrics"&gt;SimMetrics&lt;/a&gt;  &lt;/li&gt;&lt;li&gt;&lt;a href="#stringmetricsinsql"&gt;Adding string Metric functions in MS Sql Server&lt;/a&gt;  &lt;/li&gt;&lt;li&gt;&lt;a href="#comparingmetrics"&gt;Evaluating metric accuracy and comparing Metrics&lt;/a&gt;  &lt;/li&gt;&lt;li&gt;&lt;a href="#conclusion"&gt;Conclusion + code&lt;/a&gt;&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;Quite often we come across a requirement where we may need to perform some sort of fuzzy string grouping or data correlation. For example, we may want to correlate the customer records of a database by identifying records that are similar but not necessarily exactly the same (due to spelling mistakes for example). Obviously a simple group by, will not successfully group such data. We will need to employ what is commonly referred to as a distance algorithm or a string metric in order to determine how close 2 string values are. &lt;/p&gt; &lt;h3&gt;1. SoundEx &lt;a name="soundex"&gt;&lt;/a&gt;&lt;/h3&gt; &lt;p&gt;SoundEx is one such algorithm built in to Sql server, but it doesnt really perform well on calculating string value distances since it is a phonetic encoding algorithm. Vowels are ignored and the resulting value consists of a letter followed by 3 digits calculated like so:&lt;/p&gt; &lt;ol&gt; &lt;ol&gt; &lt;li&gt; &lt;p&gt;Replace consonants with digits as follows (but do not change the first letter): &lt;/p&gt; &lt;ul&gt; &lt;li&gt;b, f, p, v =&amp;gt; 1  &lt;/li&gt;&lt;li&gt;c, g, j, k, q, s, x, z =&amp;gt; 2  &lt;/li&gt;&lt;li&gt;d, t =&amp;gt; 3  &lt;/li&gt;&lt;li&gt;l =&amp;gt; 4  &lt;/li&gt;&lt;li&gt;m, n =&amp;gt; 5  &lt;/li&gt;&lt;li&gt;r =&amp;gt; 6 &lt;/li&gt;&lt;/ul&gt; &lt;/li&gt;&lt;li&gt;Collapse &lt;i&gt;adjacent&lt;/i&gt; identical digits into a single digit of that value.  &lt;/li&gt;&lt;li&gt;Remove all non-digits after the first letter.  &lt;/li&gt;&lt;li&gt;Return the starting letter and the first three remaining digits. If needed, append zeroes to make it a letter and three digits. &lt;/li&gt;&lt;/ol&gt;&lt;/ol&gt; &lt;p&gt; &lt;/p&gt; &lt;p&gt;So let's try SoundEx with a few variations and see how it performs&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: rgb(0,0,255)"&gt;select&lt;/span&gt; &lt;span style="color: rgb(255,0,255)"&gt;Soundex&lt;/span&gt;&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt;'LLoyds'&lt;/span&gt;&lt;span style="color: rgb(128,128,128)"&gt;)&lt;/span&gt; &lt;span style="color: rgb(0,128,0)"&gt;-- returns L432
&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;select&lt;/span&gt; &lt;span style="color: rgb(255,0,255)"&gt;Soundex&lt;/span&gt;&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt;'Loyds'&lt;/span&gt;&lt;span style="color: rgb(128,128,128)"&gt;)&lt;/span&gt;  &lt;span style="color: rgb(0,128,0)"&gt;-- returns L320

&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;select&lt;/span&gt; &lt;span style="color: rgb(255,0,255)"&gt;Soundex&lt;/span&gt;&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt;'Brighton'&lt;/span&gt;&lt;span style="color: rgb(128,128,128)"&gt;)&lt;/span&gt; &lt;span style="color: rgb(0,128,0)"&gt;-- returns B623
&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;select&lt;/span&gt; &lt;span style="color: rgb(255,0,255)"&gt;Soundex&lt;/span&gt;&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt;'Bristol'&lt;/span&gt;&lt;span style="color: rgb(128,128,128)"&gt;)&lt;/span&gt;  &lt;span style="color: rgb(0,128,0)"&gt;-- returns B623
&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;As you can see, Soundex returned the same code for Brighton and Bristol, while at the same time it returned a different code for Loyds and LLoyds. Such results make you think twice before employing this function in a production environment. &lt;/p&gt;
&lt;p&gt;So, is this all that is available to us? Of course not. &lt;/p&gt;
&lt;h3&gt;2. SimMetrics&lt;a name="simmetrics"&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The &lt;u&gt;&lt;font color="#669966"&gt;&lt;a href="http://nlp.shef.ac.uk/wig/"&gt;Web Intelligence Group&lt;/a&gt;&lt;/font&gt;&lt;/u&gt; within the University of Sheffield have released a wonderful library over at sourceforge just for this purpose. &lt;a href="http://sourceforge.net/projects/simmetrics/"&gt;SimMetrics&lt;/a&gt; is the library you would need to use. The developer of this library and credit for its development goes to &lt;a href="http://www.dcs.shef.ac.uk/~sam/aboutme.html"&gt;Sam Chapman&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Here are only some of the similarity metrics in SimMetrics that can be briefly described in simple English. For an even more detailed explanation and for the full list of included functions have a look over at &lt;a title="http://www.dcs.shef.ac.uk/~sam/stringmetrics.html" href="http://www.dcs.shef.ac.uk/~sam/stringmetrics.html"&gt;http://www.dcs.shef.ac.uk/~sam/stringmetrics.html&lt;/a&gt; or on &lt;a href="http://en.wikipedia.org/wiki/String_metric"&gt;Wikipedia&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.dcs.shef.ac.uk/%7Esam/stringmetrics.html#hamming"&gt;Hamming distance&lt;/a&gt;  &lt;br /&gt;Measures the minimum number of substitutions required to change one into the other&lt;br /&gt;
&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.dcs.shef.ac.uk/%7Esam/stringmetrics.html#Levenshtein"&gt;Levenshtein distance&lt;/a&gt;&lt;br /&gt;Measures the minimum number of operations needed to transform one string into the other, where an operation is an insertion, deletion, or substitution of a single character&lt;br /&gt;
&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.dcs.shef.ac.uk/%7Esam/stringmetrics.html#needleman"&gt;Needleman-Wunch distance &lt;/a&gt;or &lt;a href="http://www.dcs.shef.ac.uk/%7Esam/stringmetrics.html#sellers"&gt;Sellers Algorithm&lt;/a&gt;&lt;br /&gt;Similar to Levenstein with an added cost adjustment to the cost of a gap of the operation &lt;br /&gt;
&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.dcs.shef.ac.uk/%7Esam/stringmetrics.html#smith"&gt;Smith-Waterman distance &lt;/a&gt;&lt;br /&gt;Similar to Levenstein but with two adjustable parameters for cost functions&lt;br /&gt;
&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.dcs.shef.ac.uk/%7Esam/stringmetrics.html#gotoh"&gt;Gotoh Distance&lt;/a&gt; or &lt;a href="http://www.dcs.shef.ac.uk/%7Esam/stringmetrics.html#smithgotoh"&gt;Smith-Waterman-Gotoh distance&lt;/a&gt;&lt;br /&gt;Extension of the Smith Waterman with variable gap costs&lt;br /&gt;
&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.dcs.shef.ac.uk/%7Esam/stringmetrics.html#jaro"&gt;Jaro distance metric&lt;/a&gt;&lt;br /&gt;This distance metric is designed and best suited for short strings such as person names. The score is normalized such that 0 equates to no similarity and 1 is an exact match. The higher the distance for two strings is, the more similar the strings are&lt;br /&gt;
&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.dcs.shef.ac.uk/%7Esam/stringmetrics.html#jarowinkler"&gt;Jaro Winkler&lt;/a&gt; &lt;br /&gt;Similar to Jaro but with more favourable ratings for strings that match from the beginning&lt;br /&gt;
&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.dcs.shef.ac.uk/%7Esam/stringmetrics.html#cosine"&gt;Cosine similarity&lt;/a&gt;&lt;br /&gt;Often used to compare documents in text mining.&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;There are plenty more in this library, but frankly, the descriptions are pretty baffling and dont fit in simple one-liner explanation. Follow the links above for even more information on this. &lt;br /&gt;&lt;br /&gt;What I would like instead to focus on is how we can exploit the power of such a library within Sql Server. &lt;/p&gt;
&lt;h3&gt;3. Adding string Metric functions in MS Sql Server &lt;a name="stringmetricsinsql"&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;a href="http://anastasiosyal.com/images/anastasiosyal_com/WindowsLiveWriter/BeyondSoundExFuzzyGroupingFunctionsforMS_F0CE/image_4.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="484" alt="image" src="http://anastasiosyal.com/images/anastasiosyal_com/WindowsLiveWriter/BeyondSoundExFuzzyGroupingFunctionsforMS_F0CE/image_thumb_1.png" width="409" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;In Sql Server 2005 upwards we can leverage the power of CLR to introduce these string metrics into our SQL queries. And I will walk you through the process, step by step. &lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Download the source code of the SimMetrics library from &lt;a title="http://sourceforge.net/projects/simmetrics/" href="http://sourceforge.net/projects/simmetrics/"&gt;http://sourceforge.net/projects/simmetrics/&lt;/a&gt; 
&lt;/li&gt;&lt;li&gt;Open and compile the project so you have your SimMetrics.dll in your bin folder. 
&lt;/li&gt;&lt;li&gt;Create a new C# Class Library project and call it TextFunctions (or if you're feeling lazy, download it &lt;a href="code/textfunctions.zip"&gt;here&lt;/a&gt;) 
&lt;/li&gt;&lt;li&gt;Add a reference to the SimMetrics.dll 
&lt;/li&gt;&lt;li&gt;Add a class and call it SimMetrics 
&lt;/li&gt;&lt;li&gt;Copy and paste the following Code into your Class file&lt;/li&gt;&lt;/ol&gt;&lt;pre class="code" style="height: 300px"&gt;&lt;span style="color: rgb(0,0,255)"&gt;using&lt;/span&gt; System;
&lt;span style="color: rgb(0,0,255)"&gt;using&lt;/span&gt; System.Collections.Generic;
&lt;span style="color: rgb(0,0,255)"&gt;using&lt;/span&gt; System.Text;
&lt;span style="color: rgb(0,0,255)"&gt;using&lt;/span&gt; System.Data.SqlTypes;
&lt;span style="color: rgb(0,0,255)"&gt;using&lt;/span&gt; SimMetricsMetricUtilities;

    &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;class&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;StringMetrics
&lt;/span&gt;    {

        &lt;span style="color: rgb(0,0,255)"&gt;private&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;static&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;readonly&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;Levenstein&lt;/span&gt; _Levenstein;
        &lt;span style="color: rgb(0,0,255)"&gt;private&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;static&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;readonly&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;NeedlemanWunch&lt;/span&gt; _NeedlemanWunch;
        &lt;span style="color: rgb(0,0,255)"&gt;private&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;static&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;readonly&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;SmithWaterman&lt;/span&gt; _SmithWaterman;
        &lt;span style="color: rgb(0,0,255)"&gt;private&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;static&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;readonly&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;SmithWatermanGotoh&lt;/span&gt; _SmithWatermanGotoh;
        &lt;span style="color: rgb(0,0,255)"&gt;private&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;static&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;readonly&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;SmithWatermanGotohWindowedAffine&lt;/span&gt; _SmithWatermanGotohWindowedAffine;
        &lt;span style="color: rgb(0,0,255)"&gt;private&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;static&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;readonly&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;Jaro&lt;/span&gt; _Jaro;
        &lt;span style="color: rgb(0,0,255)"&gt;private&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;static&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;readonly&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;JaroWinkler&lt;/span&gt; _JaroWinkler;
        &lt;span style="color: rgb(0,0,255)"&gt;private&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;static&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;readonly&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;ChapmanLengthDeviation&lt;/span&gt; _ChapmanLengthDeviation;
        &lt;span style="color: rgb(0,0,255)"&gt;private&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;static&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;readonly&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;ChapmanMeanLength&lt;/span&gt; _ChapmanMeanLength;
        &lt;span style="color: rgb(0,0,255)"&gt;private&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;static&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;readonly&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;QGramsDistance&lt;/span&gt; _QGramsDistance;
        &lt;span style="color: rgb(0,0,255)"&gt;private&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;static&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;readonly&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;BlockDistance&lt;/span&gt; _BlockDistance;
        &lt;span style="color: rgb(0,0,255)"&gt;private&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;static&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;readonly&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;CosineSimilarity&lt;/span&gt; _CosineSimilarity;
        &lt;span style="color: rgb(0,0,255)"&gt;private&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;static&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;readonly&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;DiceSimilarity&lt;/span&gt; _DiceSimilarity;
        &lt;span style="color: rgb(0,0,255)"&gt;private&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;static&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;readonly&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;EuclideanDistance&lt;/span&gt; _EuclideanDistance;
        &lt;span style="color: rgb(0,0,255)"&gt;private&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;static&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;readonly&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;JaccardSimilarity&lt;/span&gt; _JaccardSimilarity;
        &lt;span style="color: rgb(0,0,255)"&gt;private&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;static&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;readonly&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;MatchingCoefficient&lt;/span&gt; _MatchingCoefficient;
        &lt;span style="color: rgb(0,0,255)"&gt;private&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;static&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;readonly&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;MongeElkan&lt;/span&gt; _MongeElkan;
        &lt;span style="color: rgb(0,0,255)"&gt;private&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;static&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;readonly&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;OverlapCoefficient&lt;/span&gt; _OverlapCoefficient;

        &lt;span style="color: rgb(0,0,255)"&gt;static&lt;/span&gt; StringMetrics()
        {
            _Levenstein = &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;Levenstein&lt;/span&gt;();
            _NeedlemanWunch = &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;NeedlemanWunch&lt;/span&gt;();
            _SmithWaterman = &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;SmithWaterman&lt;/span&gt;();
            _SmithWatermanGotoh = &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;SmithWatermanGotoh&lt;/span&gt;();
            _SmithWatermanGotohWindowedAffine = &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;SmithWatermanGotohWindowedAffine&lt;/span&gt;();
            _Jaro = &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;Jaro&lt;/span&gt;();
            _JaroWinkler = &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;JaroWinkler&lt;/span&gt;();
            _ChapmanLengthDeviation = &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;ChapmanLengthDeviation&lt;/span&gt;();
            _ChapmanMeanLength = &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;ChapmanMeanLength&lt;/span&gt;();
            _QGramsDistance = &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;QGramsDistance&lt;/span&gt;();
            _BlockDistance = &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;BlockDistance&lt;/span&gt;();
            _CosineSimilarity = &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;CosineSimilarity&lt;/span&gt;();
            _DiceSimilarity = &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;DiceSimilarity&lt;/span&gt;();
            _EuclideanDistance = &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;EuclideanDistance&lt;/span&gt;();
            _JaccardSimilarity = &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;JaccardSimilarity&lt;/span&gt;();
            _MatchingCoefficient = &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;MatchingCoefficient&lt;/span&gt;();
            _MongeElkan = &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;MongeElkan&lt;/span&gt;();
            _OverlapCoefficient = &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;OverlapCoefficient&lt;/span&gt;();
        }


        [Microsoft.SqlServer.Server.&lt;span style="color: rgb(43,145,175)"&gt;SqlFunction&lt;/span&gt;(IsDeterministic = &lt;span style="color: rgb(0,0,255)"&gt;true&lt;/span&gt;, IsPrecise = &lt;span style="color: rgb(0,0,255)"&gt;true&lt;/span&gt;)]
        &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;static&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;SqlDouble&lt;/span&gt; Levenstein(&lt;span style="color: rgb(43,145,175)"&gt;SqlString&lt;/span&gt; firstWord, &lt;span style="color: rgb(43,145,175)"&gt;SqlString&lt;/span&gt; secondWord)
        {
            &lt;span style="color: rgb(0,0,255)"&gt;if&lt;/span&gt; (firstWord.IsNull || secondWord.IsNull)
                &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; 0;

            &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;SqlDouble&lt;/span&gt;(_Levenstein.GetSimilarity(firstWord.Value, secondWord.Value));
        }


        [Microsoft.SqlServer.Server.&lt;span style="color: rgb(43,145,175)"&gt;SqlFunction&lt;/span&gt;(IsDeterministic = &lt;span style="color: rgb(0,0,255)"&gt;true&lt;/span&gt;, IsPrecise = &lt;span style="color: rgb(0,0,255)"&gt;true&lt;/span&gt;)]
        &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;static&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;SqlDouble&lt;/span&gt; NeedlemanWunch(&lt;span style="color: rgb(43,145,175)"&gt;SqlString&lt;/span&gt; firstWord, &lt;span style="color: rgb(43,145,175)"&gt;SqlString&lt;/span&gt; secondWord)
        {
            &lt;span style="color: rgb(0,0,255)"&gt;if&lt;/span&gt; (firstWord.IsNull || secondWord.IsNull)
                &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; 0;

            &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;SqlDouble&lt;/span&gt;(_NeedlemanWunch.GetSimilarity(firstWord.Value, secondWord.Value));
        }


        [Microsoft.SqlServer.Server.&lt;span style="color: rgb(43,145,175)"&gt;SqlFunction&lt;/span&gt;(IsDeterministic = &lt;span style="color: rgb(0,0,255)"&gt;true&lt;/span&gt;, IsPrecise = &lt;span style="color: rgb(0,0,255)"&gt;true&lt;/span&gt;)]
        &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;static&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;SqlDouble&lt;/span&gt; SmithWaterman(&lt;span style="color: rgb(43,145,175)"&gt;SqlString&lt;/span&gt; firstWord, &lt;span style="color: rgb(43,145,175)"&gt;SqlString&lt;/span&gt; secondWord)
        {
            &lt;span style="color: rgb(0,0,255)"&gt;if&lt;/span&gt; (firstWord.IsNull || secondWord.IsNull)
                &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; 0;

            &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;SqlDouble&lt;/span&gt;(_SmithWaterman.GetSimilarity(firstWord.Value, secondWord.Value));
        }


        [Microsoft.SqlServer.Server.&lt;span style="color: rgb(43,145,175)"&gt;SqlFunction&lt;/span&gt;(IsDeterministic = &lt;span style="color: rgb(0,0,255)"&gt;true&lt;/span&gt;, IsPrecise = &lt;span style="color: rgb(0,0,255)"&gt;true&lt;/span&gt;)]
        &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;static&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;SqlDouble&lt;/span&gt; SmithWatermanGotoh(&lt;span style="color: rgb(43,145,175)"&gt;SqlString&lt;/span&gt; firstWord, &lt;span style="color: rgb(43,145,175)"&gt;SqlString&lt;/span&gt; secondWord)
        {
            &lt;span style="color: rgb(0,0,255)"&gt;if&lt;/span&gt; (firstWord.IsNull || secondWord.IsNull)
                &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; 0;

            &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;SqlDouble&lt;/span&gt;(_SmithWatermanGotoh.GetSimilarity(firstWord.Value, secondWord.Value));
        }


        [Microsoft.SqlServer.Server.&lt;span style="color: rgb(43,145,175)"&gt;SqlFunction&lt;/span&gt;(IsDeterministic = &lt;span style="color: rgb(0,0,255)"&gt;true&lt;/span&gt;, IsPrecise = &lt;span style="color: rgb(0,0,255)"&gt;true&lt;/span&gt;)]
        &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;static&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;SqlDouble&lt;/span&gt; SmithWatermanGotohWindowedAffine(&lt;span style="color: rgb(43,145,175)"&gt;SqlString&lt;/span&gt; firstWord, &lt;span style="color: rgb(43,145,175)"&gt;SqlString&lt;/span&gt; secondWord)
        {
            &lt;span style="color: rgb(0,0,255)"&gt;if&lt;/span&gt; (firstWord.IsNull || secondWord.IsNull)
                &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; 0;

            &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;SqlDouble&lt;/span&gt;(_SmithWatermanGotohWindowedAffine.GetSimilarity(firstWord.Value, secondWord.Value));
        }


        [Microsoft.SqlServer.Server.&lt;span style="color: rgb(43,145,175)"&gt;SqlFunction&lt;/span&gt;(IsDeterministic = &lt;span style="color: rgb(0,0,255)"&gt;true&lt;/span&gt;, IsPrecise = &lt;span style="color: rgb(0,0,255)"&gt;true&lt;/span&gt;)]
        &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;static&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;SqlDouble&lt;/span&gt; Jaro(&lt;span style="color: rgb(43,145,175)"&gt;SqlString&lt;/span&gt; firstWord, &lt;span style="color: rgb(43,145,175)"&gt;SqlString&lt;/span&gt; secondWord)
        {
            &lt;span style="color: rgb(0,0,255)"&gt;if&lt;/span&gt; (firstWord.IsNull || secondWord.IsNull)
                &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; 0;

            &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;SqlDouble&lt;/span&gt;(_Jaro.GetSimilarity(firstWord.Value, secondWord.Value));
        }


        [Microsoft.SqlServer.Server.&lt;span style="color: rgb(43,145,175)"&gt;SqlFunction&lt;/span&gt;(IsDeterministic = &lt;span style="color: rgb(0,0,255)"&gt;true&lt;/span&gt;, IsPrecise = &lt;span style="color: rgb(0,0,255)"&gt;true&lt;/span&gt;)]
        &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;static&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;SqlDouble&lt;/span&gt; JaroWinkler(&lt;span style="color: rgb(43,145,175)"&gt;SqlString&lt;/span&gt; firstWord, &lt;span style="color: rgb(43,145,175)"&gt;SqlString&lt;/span&gt; secondWord)
        {
            &lt;span style="color: rgb(0,0,255)"&gt;if&lt;/span&gt; (firstWord.IsNull || secondWord.IsNull)
                &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; 0;

            &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;SqlDouble&lt;/span&gt;(_JaroWinkler.GetSimilarity(firstWord.Value, secondWord.Value));
        }


        [Microsoft.SqlServer.Server.&lt;span style="color: rgb(43,145,175)"&gt;SqlFunction&lt;/span&gt;(IsDeterministic = &lt;span style="color: rgb(0,0,255)"&gt;true&lt;/span&gt;, IsPrecise = &lt;span style="color: rgb(0,0,255)"&gt;true&lt;/span&gt;)]
        &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;static&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;SqlDouble&lt;/span&gt; ChapmanLengthDeviation(&lt;span style="color: rgb(43,145,175)"&gt;SqlString&lt;/span&gt; firstWord, &lt;span style="color: rgb(43,145,175)"&gt;SqlString&lt;/span&gt; secondWord)
        {
            &lt;span style="color: rgb(0,0,255)"&gt;if&lt;/span&gt; (firstWord.IsNull || secondWord.IsNull)
                &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; 0;

            &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;SqlDouble&lt;/span&gt;(_ChapmanLengthDeviation.GetSimilarity(firstWord.Value, secondWord.Value));
        }


        [Microsoft.SqlServer.Server.&lt;span style="color: rgb(43,145,175)"&gt;SqlFunction&lt;/span&gt;(IsDeterministic = &lt;span style="color: rgb(0,0,255)"&gt;true&lt;/span&gt;, IsPrecise = &lt;span style="color: rgb(0,0,255)"&gt;true&lt;/span&gt;)]
        &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;static&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;SqlDouble&lt;/span&gt; ChapmanMeanLength(&lt;span style="color: rgb(43,145,175)"&gt;SqlString&lt;/span&gt; firstWord, &lt;span style="color: rgb(43,145,175)"&gt;SqlString&lt;/span&gt; secondWord)
        {
            &lt;span style="color: rgb(0,0,255)"&gt;if&lt;/span&gt; (firstWord.IsNull || secondWord.IsNull)
                &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; 0;

            &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;SqlDouble&lt;/span&gt;(_ChapmanMeanLength.GetSimilarity(firstWord.Value, secondWord.Value));
        }


        [Microsoft.SqlServer.Server.&lt;span style="color: rgb(43,145,175)"&gt;SqlFunction&lt;/span&gt;(IsDeterministic = &lt;span style="color: rgb(0,0,255)"&gt;true&lt;/span&gt;, IsPrecise = &lt;span style="color: rgb(0,0,255)"&gt;true&lt;/span&gt;)]
        &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;static&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;SqlDouble&lt;/span&gt; QGramsDistance(&lt;span style="color: rgb(43,145,175)"&gt;SqlString&lt;/span&gt; firstWord, &lt;span style="color: rgb(43,145,175)"&gt;SqlString&lt;/span&gt; secondWord)
        {
            &lt;span style="color: rgb(0,0,255)"&gt;if&lt;/span&gt; (firstWord.IsNull || secondWord.IsNull)
                &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; 0;

            &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;SqlDouble&lt;/span&gt;(_QGramsDistance.GetSimilarity(firstWord.Value, secondWord.Value));
        }


        [Microsoft.SqlServer.Server.&lt;span style="color: rgb(43,145,175)"&gt;SqlFunction&lt;/span&gt;(IsDeterministic = &lt;span style="color: rgb(0,0,255)"&gt;true&lt;/span&gt;, IsPrecise = &lt;span style="color: rgb(0,0,255)"&gt;true&lt;/span&gt;)]
        &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;static&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;SqlDouble&lt;/span&gt; BlockDistance(&lt;span style="color: rgb(43,145,175)"&gt;SqlString&lt;/span&gt; firstWord, &lt;span style="color: rgb(43,145,175)"&gt;SqlString&lt;/span&gt; secondWord)
        {
            &lt;span style="color: rgb(0,0,255)"&gt;if&lt;/span&gt; (firstWord.IsNull || secondWord.IsNull)
                &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; 0;

            &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;SqlDouble&lt;/span&gt;(_BlockDistance.GetSimilarity(firstWord.Value, secondWord.Value));
        }


        [Microsoft.SqlServer.Server.&lt;span style="color: rgb(43,145,175)"&gt;SqlFunction&lt;/span&gt;(IsDeterministic = &lt;span style="color: rgb(0,0,255)"&gt;true&lt;/span&gt;, IsPrecise = &lt;span style="color: rgb(0,0,255)"&gt;true&lt;/span&gt;)]
        &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;static&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;SqlDouble&lt;/span&gt; CosineSimilarity(&lt;span style="color: rgb(43,145,175)"&gt;SqlString&lt;/span&gt; firstWord, &lt;span style="color: rgb(43,145,175)"&gt;SqlString&lt;/span&gt; secondWord)
        {
            &lt;span style="color: rgb(0,0,255)"&gt;if&lt;/span&gt; (firstWord.IsNull || secondWord.IsNull)
                &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; 0;

            &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;SqlDouble&lt;/span&gt;(_CosineSimilarity.GetSimilarity(firstWord.Value, secondWord.Value));
        }


        [Microsoft.SqlServer.Server.&lt;span style="color: rgb(43,145,175)"&gt;SqlFunction&lt;/span&gt;(IsDeterministic = &lt;span style="color: rgb(0,0,255)"&gt;true&lt;/span&gt;, IsPrecise = &lt;span style="color: rgb(0,0,255)"&gt;true&lt;/span&gt;)]
        &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;static&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;SqlDouble&lt;/span&gt; DiceSimilarity(&lt;span style="color: rgb(43,145,175)"&gt;SqlString&lt;/span&gt; firstWord, &lt;span style="color: rgb(43,145,175)"&gt;SqlString&lt;/span&gt; secondWord)
        {
            &lt;span style="color: rgb(0,0,255)"&gt;if&lt;/span&gt; (firstWord.IsNull || secondWord.IsNull)
                &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; 0;

            &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;SqlDouble&lt;/span&gt;(_DiceSimilarity.GetSimilarity(firstWord.Value, secondWord.Value));
        }

        [Microsoft.SqlServer.Server.&lt;span style="color: rgb(43,145,175)"&gt;SqlFunction&lt;/span&gt;(IsDeterministic = &lt;span style="color: rgb(0,0,255)"&gt;true&lt;/span&gt;, IsPrecise = &lt;span style="color: rgb(0,0,255)"&gt;true&lt;/span&gt;)]
        &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;static&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;SqlDouble&lt;/span&gt; EuclideanDistance(&lt;span style="color: rgb(43,145,175)"&gt;SqlString&lt;/span&gt; firstWord, &lt;span style="color: rgb(43,145,175)"&gt;SqlString&lt;/span&gt; secondWord)
        {
            &lt;span style="color: rgb(0,0,255)"&gt;if&lt;/span&gt; (firstWord.IsNull || secondWord.IsNull)
                &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; 0;

            &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;SqlDouble&lt;/span&gt;(_EuclideanDistance.GetSimilarity(firstWord.Value, secondWord.Value));
        }


        [Microsoft.SqlServer.Server.&lt;span style="color: rgb(43,145,175)"&gt;SqlFunction&lt;/span&gt;(IsDeterministic = &lt;span style="color: rgb(0,0,255)"&gt;true&lt;/span&gt;, IsPrecise = &lt;span style="color: rgb(0,0,255)"&gt;true&lt;/span&gt;)]
        &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;static&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;SqlDouble&lt;/span&gt; JaccardSimilarity(&lt;span style="color: rgb(43,145,175)"&gt;SqlString&lt;/span&gt; firstWord, &lt;span style="color: rgb(43,145,175)"&gt;SqlString&lt;/span&gt; secondWord)
        {
            &lt;span style="color: rgb(0,0,255)"&gt;if&lt;/span&gt; (firstWord.IsNull || secondWord.IsNull)
                &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; 0;

            &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;SqlDouble&lt;/span&gt;(_JaccardSimilarity.GetSimilarity(firstWord.Value, secondWord.Value));
        }


        [Microsoft.SqlServer.Server.&lt;span style="color: rgb(43,145,175)"&gt;SqlFunction&lt;/span&gt;(IsDeterministic = &lt;span style="color: rgb(0,0,255)"&gt;true&lt;/span&gt;, IsPrecise = &lt;span style="color: rgb(0,0,255)"&gt;true&lt;/span&gt;)]
        &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;static&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;SqlDouble&lt;/span&gt; MatchingCoefficient(&lt;span style="color: rgb(43,145,175)"&gt;SqlString&lt;/span&gt; firstWord, &lt;span style="color: rgb(43,145,175)"&gt;SqlString&lt;/span&gt; secondWord)
        {
            &lt;span style="color: rgb(0,0,255)"&gt;if&lt;/span&gt; (firstWord.IsNull || secondWord.IsNull)
                &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; 0;

            &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;SqlDouble&lt;/span&gt;(_MatchingCoefficient.GetSimilarity(firstWord.Value, secondWord.Value));
        }


        [Microsoft.SqlServer.Server.&lt;span style="color: rgb(43,145,175)"&gt;SqlFunction&lt;/span&gt;(IsDeterministic = &lt;span style="color: rgb(0,0,255)"&gt;true&lt;/span&gt;, IsPrecise = &lt;span style="color: rgb(0,0,255)"&gt;true&lt;/span&gt;)]
        &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;static&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;SqlDouble&lt;/span&gt; MongeElkan(&lt;span style="color: rgb(43,145,175)"&gt;SqlString&lt;/span&gt; firstWord, &lt;span style="color: rgb(43,145,175)"&gt;SqlString&lt;/span&gt; secondWord)
        {
            &lt;span style="color: rgb(0,0,255)"&gt;if&lt;/span&gt; (firstWord.IsNull || secondWord.IsNull)
                &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; 0;

            &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;SqlDouble&lt;/span&gt;(_MongeElkan.GetSimilarity(firstWord.Value, secondWord.Value));
        }


        [Microsoft.SqlServer.Server.&lt;span style="color: rgb(43,145,175)"&gt;SqlFunction&lt;/span&gt;(IsDeterministic = &lt;span style="color: rgb(0,0,255)"&gt;true&lt;/span&gt;, IsPrecise = &lt;span style="color: rgb(0,0,255)"&gt;true&lt;/span&gt;)]
        &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;static&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;SqlDouble&lt;/span&gt; OverlapCoefficient(&lt;span style="color: rgb(43,145,175)"&gt;SqlString&lt;/span&gt; firstWord, &lt;span style="color: rgb(43,145,175)"&gt;SqlString&lt;/span&gt; secondWord)
        {
            &lt;span style="color: rgb(0,0,255)"&gt;if&lt;/span&gt; (firstWord.IsNull || secondWord.IsNull)
                &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; 0;

            &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;SqlDouble&lt;/span&gt;(_OverlapCoefficient.GetSimilarity(firstWord.Value, secondWord.Value));
        }


    }
&lt;/pre&gt;
&lt;p&gt; &lt;/p&gt;
&lt;ol start="7"&gt;
&lt;li&gt;Compile your project and copy the path to your dll. 
&lt;/li&gt;&lt;li&gt;We need to make sure that our target sql server is CLR Enabled so we need to run:&lt;/li&gt;&lt;/ol&gt;&lt;pre class="code"&gt;&lt;span style="color: rgb(0,0,255)"&gt;EXEC&lt;/span&gt; &lt;span style="color: rgb(128,0,0)"&gt;sp_configure&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt; &lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt;'clr enabled'&lt;/span&gt;&lt;span style="color: rgb(128,128,128)"&gt;,&lt;/span&gt; 1
&lt;span style="color: rgb(0,0,255)"&gt;RECONFIGURE&lt;/span&gt;&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;ol start="9"&gt;
&lt;li&gt;Install the library and the functions onto SQL Server&lt;/li&gt;&lt;/ol&gt;&lt;pre class="code" style="height: 300px"&gt;&lt;span style="color: rgb(0,0,255)"&gt;CREATE&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;ASSEMBLY&lt;/span&gt; [TextFunctions]
&lt;span style="color: rgb(0,0,255)"&gt;AUTHORIZATION&lt;/span&gt; [dbo]
&lt;span style="color: rgb(0,0,255)"&gt;FROM&lt;/span&gt; &lt;span style="color: rgb(255,0,0)"&gt;'c:\SqlAssembly\TextFunctions.dll'
&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;WITH&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;PERMISSION_SET&lt;/span&gt; &lt;span style="color: rgb(128,128,128)"&gt;=&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;SAFE

GO

CREATE&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;FUNCTION&lt;/span&gt; Levenstein&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;@firstword &lt;span style="color: rgb(0,0,255)"&gt;NVARCHAR&lt;/span&gt;&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;255&lt;span style="color: rgb(128,128,128)"&gt;),&lt;/span&gt;@secondword &lt;span style="color: rgb(0,0,255)"&gt;NVARCHAR&lt;/span&gt;&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;255&lt;span style="color: rgb(128,128,128)"&gt;))
&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;RETURNS&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;float&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;EXTERNAL&lt;/span&gt; NAME TextFunctions&lt;span style="color: rgb(128,128,128)"&gt;.&lt;/span&gt;StringMetrics&lt;span style="color: rgb(128,128,128)"&gt;.&lt;/span&gt;Levenstein
&lt;span style="color: rgb(0,0,255)"&gt;GO

CREATE&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;FUNCTION&lt;/span&gt; NeedlemanWunch&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;@firstword &lt;span style="color: rgb(0,0,255)"&gt;NVARCHAR&lt;/span&gt;&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;255&lt;span style="color: rgb(128,128,128)"&gt;),&lt;/span&gt;@secondword &lt;span style="color: rgb(0,0,255)"&gt;NVARCHAR&lt;/span&gt;&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;255&lt;span style="color: rgb(128,128,128)"&gt;))
&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;RETURNS&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;float&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;EXTERNAL&lt;/span&gt; NAME TextFunctions&lt;span style="color: rgb(128,128,128)"&gt;.&lt;/span&gt;StringMetrics&lt;span style="color: rgb(128,128,128)"&gt;.&lt;/span&gt;NeedlemanWunch
&lt;span style="color: rgb(0,0,255)"&gt;GO

CREATE&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;FUNCTION&lt;/span&gt; SmithWaterman&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;@firstword &lt;span style="color: rgb(0,0,255)"&gt;NVARCHAR&lt;/span&gt;&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;255&lt;span style="color: rgb(128,128,128)"&gt;),&lt;/span&gt;@secondword &lt;span style="color: rgb(0,0,255)"&gt;NVARCHAR&lt;/span&gt;&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;255&lt;span style="color: rgb(128,128,128)"&gt;))
&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;RETURNS&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;float&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;EXTERNAL&lt;/span&gt; NAME TextFunctions&lt;span style="color: rgb(128,128,128)"&gt;.&lt;/span&gt;StringMetrics&lt;span style="color: rgb(128,128,128)"&gt;.&lt;/span&gt;SmithWaterman
&lt;span style="color: rgb(0,0,255)"&gt;GO

CREATE&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;FUNCTION&lt;/span&gt; SmithWatermanGotoh&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;@firstword &lt;span style="color: rgb(0,0,255)"&gt;NVARCHAR&lt;/span&gt;&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;255&lt;span style="color: rgb(128,128,128)"&gt;),&lt;/span&gt;@secondword &lt;span style="color: rgb(0,0,255)"&gt;NVARCHAR&lt;/span&gt;&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;255&lt;span style="color: rgb(128,128,128)"&gt;))
&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;RETURNS&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;float&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;EXTERNAL&lt;/span&gt; NAME TextFunctions&lt;span style="color: rgb(128,128,128)"&gt;.&lt;/span&gt;StringMetrics&lt;span style="color: rgb(128,128,128)"&gt;.&lt;/span&gt;SmithWatermanGotoh
&lt;span style="color: rgb(0,0,255)"&gt;GO

CREATE&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;FUNCTION&lt;/span&gt; SmithWatermanGotohWindowedAffine&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;@firstword &lt;span style="color: rgb(0,0,255)"&gt;NVARCHAR&lt;/span&gt;&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;255&lt;span style="color: rgb(128,128,128)"&gt;),&lt;/span&gt;@secondword &lt;span style="color: rgb(0,0,255)"&gt;NVARCHAR&lt;/span&gt;&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;255&lt;span style="color: rgb(128,128,128)"&gt;))
&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;RETURNS&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;float&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;EXTERNAL&lt;/span&gt; NAME TextFunctions&lt;span style="color: rgb(128,128,128)"&gt;.&lt;/span&gt;StringMetrics&lt;span style="color: rgb(128,128,128)"&gt;.&lt;/span&gt;SmithWatermanGotohWindowedAffine
&lt;span style="color: rgb(0,0,255)"&gt;GO

CREATE&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;FUNCTION&lt;/span&gt; Jaro&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;@firstword &lt;span style="color: rgb(0,0,255)"&gt;NVARCHAR&lt;/span&gt;&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;255&lt;span style="color: rgb(128,128,128)"&gt;),&lt;/span&gt;@secondword &lt;span style="color: rgb(0,0,255)"&gt;NVARCHAR&lt;/span&gt;&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;255&lt;span style="color: rgb(128,128,128)"&gt;))
&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;RETURNS&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;float&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;EXTERNAL&lt;/span&gt; NAME TextFunctions&lt;span style="color: rgb(128,128,128)"&gt;.&lt;/span&gt;StringMetrics&lt;span style="color: rgb(128,128,128)"&gt;.&lt;/span&gt;Jaro
&lt;span style="color: rgb(0,0,255)"&gt;GO

CREATE&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;FUNCTION&lt;/span&gt; JaroWinkler&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;@firstword &lt;span style="color: rgb(0,0,255)"&gt;NVARCHAR&lt;/span&gt;&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;255&lt;span style="color: rgb(128,128,128)"&gt;),&lt;/span&gt;@secondword &lt;span style="color: rgb(0,0,255)"&gt;NVARCHAR&lt;/span&gt;&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;255&lt;span style="color: rgb(128,128,128)"&gt;))
&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;RETURNS&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;float&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;EXTERNAL&lt;/span&gt; NAME TextFunctions&lt;span style="color: rgb(128,128,128)"&gt;.&lt;/span&gt;StringMetrics&lt;span style="color: rgb(128,128,128)"&gt;.&lt;/span&gt;JaroWinkler
&lt;span style="color: rgb(0,0,255)"&gt;GO

CREATE&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;FUNCTION&lt;/span&gt; ChapmanLengthDeviation&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;@firstword &lt;span style="color: rgb(0,0,255)"&gt;NVARCHAR&lt;/span&gt;&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;255&lt;span style="color: rgb(128,128,128)"&gt;),&lt;/span&gt;@secondword &lt;span style="color: rgb(0,0,255)"&gt;NVARCHAR&lt;/span&gt;&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;255&lt;span style="color: rgb(128,128,128)"&gt;))
&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;RETURNS&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;float&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;EXTERNAL&lt;/span&gt; NAME TextFunctions&lt;span style="color: rgb(128,128,128)"&gt;.&lt;/span&gt;StringMetrics&lt;span style="color: rgb(128,128,128)"&gt;.&lt;/span&gt;ChapmanLengthDeviation
&lt;span style="color: rgb(0,0,255)"&gt;GO

CREATE&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;FUNCTION&lt;/span&gt; ChapmanMeanLength&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;@firstword &lt;span style="color: rgb(0,0,255)"&gt;NVARCHAR&lt;/span&gt;&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;255&lt;span style="color: rgb(128,128,128)"&gt;),&lt;/span&gt;@secondword &lt;span style="color: rgb(0,0,255)"&gt;NVARCHAR&lt;/span&gt;&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;255&lt;span style="color: rgb(128,128,128)"&gt;))
&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;RETURNS&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;float&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;EXTERNAL&lt;/span&gt; NAME TextFunctions&lt;span style="color: rgb(128,128,128)"&gt;.&lt;/span&gt;StringMetrics&lt;span style="color: rgb(128,128,128)"&gt;.&lt;/span&gt;ChapmanMeanLength
&lt;span style="color: rgb(0,0,255)"&gt;GO

CREATE&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;FUNCTION&lt;/span&gt; QGramsDistance&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;@firstword &lt;span style="color: rgb(0,0,255)"&gt;NVARCHAR&lt;/span&gt;&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;255&lt;span style="color: rgb(128,128,128)"&gt;),&lt;/span&gt;@secondword &lt;span style="color: rgb(0,0,255)"&gt;NVARCHAR&lt;/span&gt;&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;255&lt;span style="color: rgb(128,128,128)"&gt;))
&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;RETURNS&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;float&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;EXTERNAL&lt;/span&gt; NAME TextFunctions&lt;span style="color: rgb(128,128,128)"&gt;.&lt;/span&gt;StringMetrics&lt;span style="color: rgb(128,128,128)"&gt;.&lt;/span&gt;QGramsDistance
&lt;span style="color: rgb(0,0,255)"&gt;GO

CREATE&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;FUNCTION&lt;/span&gt; BlockDistance&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;@firstword &lt;span style="color: rgb(0,0,255)"&gt;NVARCHAR&lt;/span&gt;&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;255&lt;span style="color: rgb(128,128,128)"&gt;),&lt;/span&gt;@secondword &lt;span style="color: rgb(0,0,255)"&gt;NVARCHAR&lt;/span&gt;&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;255&lt;span style="color: rgb(128,128,128)"&gt;))
&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;RETURNS&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;float&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;EXTERNAL&lt;/span&gt; NAME TextFunctions&lt;span style="color: rgb(128,128,128)"&gt;.&lt;/span&gt;StringMetrics&lt;span style="color: rgb(128,128,128)"&gt;.&lt;/span&gt;BlockDistance
&lt;span style="color: rgb(0,0,255)"&gt;GO

CREATE&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;FUNCTION&lt;/span&gt; CosineSimilarity&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;@firstword &lt;span style="color: rgb(0,0,255)"&gt;NVARCHAR&lt;/span&gt;&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;255&lt;span style="color: rgb(128,128,128)"&gt;),&lt;/span&gt;@secondword &lt;span style="color: rgb(0,0,255)"&gt;NVARCHAR&lt;/span&gt;&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;255&lt;span style="color: rgb(128,128,128)"&gt;))
&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;RETURNS&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;float&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;EXTERNAL&lt;/span&gt; NAME TextFunctions&lt;span style="color: rgb(128,128,128)"&gt;.&lt;/span&gt;StringMetrics&lt;span style="color: rgb(128,128,128)"&gt;.&lt;/span&gt;CosineSimilarity
&lt;span style="color: rgb(0,0,255)"&gt;GO

CREATE&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;FUNCTION&lt;/span&gt; DiceSimilarity&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;@firstword &lt;span style="color: rgb(0,0,255)"&gt;NVARCHAR&lt;/span&gt;&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;255&lt;span style="color: rgb(128,128,128)"&gt;),&lt;/span&gt;@secondword &lt;span style="color: rgb(0,0,255)"&gt;NVARCHAR&lt;/span&gt;&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;255&lt;span style="color: rgb(128,128,128)"&gt;))
&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;RETURNS&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;float&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;EXTERNAL&lt;/span&gt; NAME TextFunctions&lt;span style="color: rgb(128,128,128)"&gt;.&lt;/span&gt;StringMetrics&lt;span style="color: rgb(128,128,128)"&gt;.&lt;/span&gt;DiceSimilarity
&lt;span style="color: rgb(0,0,255)"&gt;GO

CREATE&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;FUNCTION&lt;/span&gt; EuclideanDistance&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;@firstword &lt;span style="color: rgb(0,0,255)"&gt;NVARCHAR&lt;/span&gt;&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;255&lt;span style="color: rgb(128,128,128)"&gt;),&lt;/span&gt;@secondword &lt;span style="color: rgb(0,0,255)"&gt;NVARCHAR&lt;/span&gt;&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;255&lt;span style="color: rgb(128,128,128)"&gt;))
&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;RETURNS&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;float&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;EXTERNAL&lt;/span&gt; NAME TextFunctions&lt;span style="color: rgb(128,128,128)"&gt;.&lt;/span&gt;StringMetrics&lt;span style="color: rgb(128,128,128)"&gt;.&lt;/span&gt;EuclideanDistance
&lt;span style="color: rgb(0,0,255)"&gt;GO

CREATE&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;FUNCTION&lt;/span&gt; JaccardSimilarity&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;@firstword &lt;span style="color: rgb(0,0,255)"&gt;NVARCHAR&lt;/span&gt;&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;255&lt;span style="color: rgb(128,128,128)"&gt;),&lt;/span&gt;@secondword &lt;span style="color: rgb(0,0,255)"&gt;NVARCHAR&lt;/span&gt;&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;255&lt;span style="color: rgb(128,128,128)"&gt;))
&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;RETURNS&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;float&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;EXTERNAL&lt;/span&gt; NAME TextFunctions&lt;span style="color: rgb(128,128,128)"&gt;.&lt;/span&gt;StringMetrics&lt;span style="color: rgb(128,128,128)"&gt;.&lt;/span&gt;JaccardSimilarity
&lt;span style="color: rgb(0,0,255)"&gt;GO

CREATE&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;FUNCTION&lt;/span&gt; MatchingCoefficient&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;@firstword &lt;span style="color: rgb(0,0,255)"&gt;NVARCHAR&lt;/span&gt;&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;255&lt;span style="color: rgb(128,128,128)"&gt;),&lt;/span&gt;@secondword &lt;span style="color: rgb(0,0,255)"&gt;NVARCHAR&lt;/span&gt;&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;255&lt;span style="color: rgb(128,128,128)"&gt;))
&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;RETURNS&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;float&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;EXTERNAL&lt;/span&gt; NAME TextFunctions&lt;span style="color: rgb(128,128,128)"&gt;.&lt;/span&gt;StringMetrics&lt;span style="color: rgb(128,128,128)"&gt;.&lt;/span&gt;MatchingCoefficient
&lt;span style="color: rgb(0,0,255)"&gt;GO

CREATE&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;FUNCTION&lt;/span&gt; MongeElkan&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;@firstword &lt;span style="color: rgb(0,0,255)"&gt;NVARCHAR&lt;/span&gt;&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;255&lt;span style="color: rgb(128,128,128)"&gt;),&lt;/span&gt;@secondword &lt;span style="color: rgb(0,0,255)"&gt;NVARCHAR&lt;/span&gt;&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;255&lt;span style="color: rgb(128,128,128)"&gt;))
&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;RETURNS&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;float&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;EXTERNAL&lt;/span&gt; NAME TextFunctions&lt;span style="color: rgb(128,128,128)"&gt;.&lt;/span&gt;StringMetrics&lt;span style="color: rgb(128,128,128)"&gt;.&lt;/span&gt;MongeElkan
&lt;span style="color: rgb(0,0,255)"&gt;GO

CREATE&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;FUNCTION&lt;/span&gt; OverlapCoefficient&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;@firstword &lt;span style="color: rgb(0,0,255)"&gt;NVARCHAR&lt;/span&gt;&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;255&lt;span style="color: rgb(128,128,128)"&gt;),&lt;/span&gt;@secondword &lt;span style="color: rgb(0,0,255)"&gt;NVARCHAR&lt;/span&gt;&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;255&lt;span style="color: rgb(128,128,128)"&gt;))
&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;RETURNS&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;float&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;EXTERNAL&lt;/span&gt; NAME TextFunctions&lt;span style="color: rgb(128,128,128)"&gt;.&lt;/span&gt;StringMetrics&lt;span style="color: rgb(128,128,128)"&gt;.&lt;/span&gt;OverlapCoefficient
&lt;span style="color: rgb(0,0,255)"&gt;GO
&lt;/span&gt;&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;h3 /&gt;
&lt;h3 /&gt;
&lt;ol start="10"&gt;
&lt;li&gt;Now we are ready to use the functions our newly available string metrics functions.&lt;/li&gt;&lt;/ol&gt;
&lt;h3&gt;4. Evaluating metric accuracy and comparing Metrics &lt;a name="comparingmetrics"&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;All string metric functions accept two string arguments and return a float value between 0 and 1. The closer the score reaches 1 means that the metric we have applied is telling us the 2 input strings are a match.&lt;/p&gt;
&lt;p&gt;Now that we have plenty of Metrics to choose from, we will want to evaluate them and see which one is best for us. This is where the following function comes in handy:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: rgb(0,0,255)"&gt;CREATE&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;FUNCTION&lt;/span&gt; dbo&lt;span style="color: rgb(128,128,128)"&gt;.&lt;/span&gt;CompareStringMetrics&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;@firstword [nvarchar]&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;255&lt;span style="color: rgb(128,128,128)"&gt;),&lt;/span&gt; @secondword [nvarchar]&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;255&lt;span style="color: rgb(128,128,128)"&gt;))
&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;RETURNS&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;TABLE
AS
RETURN
&lt;/span&gt;&lt;span style="color: rgb(128,128,128)"&gt;(
&lt;/span&gt;    &lt;span style="color: rgb(0,0,255)"&gt;SELECT&lt;/span&gt; dbo&lt;span style="color: rgb(128,128,128)"&gt;.&lt;/span&gt;Jaro&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;@firstword&lt;span style="color: rgb(128,128,128)"&gt;,&lt;/span&gt; @secondword&lt;span style="color: rgb(128,128,128)"&gt;)&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;as&lt;/span&gt; Score&lt;span style="color: rgb(128,128,128)"&gt;,&lt;/span&gt; &lt;span style="color: rgb(255,0,0)"&gt;'Jaro'&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;as&lt;/span&gt; Metric
    &lt;span style="color: rgb(0,0,255)"&gt;UNION&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;SELECT&lt;/span&gt; dbo&lt;span style="color: rgb(128,128,128)"&gt;.&lt;/span&gt;JaroWinkler&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;@firstword&lt;span style="color: rgb(128,128,128)"&gt;,&lt;/span&gt; @secondword&lt;span style="color: rgb(128,128,128)"&gt;),&lt;/span&gt; &lt;span style="color: rgb(255,0,0)"&gt;'JaroWinkler'
&lt;/span&gt;    &lt;span style="color: rgb(0,0,255)"&gt;UNION&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;SELECT&lt;/span&gt; dbo&lt;span style="color: rgb(128,128,128)"&gt;.&lt;/span&gt;BlockDistance&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;@firstword&lt;span style="color: rgb(128,128,128)"&gt;,&lt;/span&gt; @secondword&lt;span style="color: rgb(128,128,128)"&gt;),&lt;/span&gt; &lt;span style="color: rgb(255,0,0)"&gt;'BlockDistance'
&lt;/span&gt;    &lt;span style="color: rgb(0,0,255)"&gt;UNION&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;SELECT&lt;/span&gt; dbo&lt;span style="color: rgb(128,128,128)"&gt;.&lt;/span&gt;ChapmanLengthDeviation&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;@firstword&lt;span style="color: rgb(128,128,128)"&gt;,&lt;/span&gt; @secondword&lt;span style="color: rgb(128,128,128)"&gt;),&lt;/span&gt; &lt;span style="color: rgb(255,0,0)"&gt;'ChapmanLengthDeviation'
&lt;/span&gt;    &lt;span style="color: rgb(0,0,255)"&gt;UNION&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;SELECT&lt;/span&gt; dbo&lt;span style="color: rgb(128,128,128)"&gt;.&lt;/span&gt;ChapmanMeanLength&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;@firstword&lt;span style="color: rgb(128,128,128)"&gt;,&lt;/span&gt; @secondword&lt;span style="color: rgb(128,128,128)"&gt;),&lt;/span&gt; &lt;span style="color: rgb(255,0,0)"&gt;'ChapmanMeanLength'
&lt;/span&gt;    &lt;span style="color: rgb(0,0,255)"&gt;UNION&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;SELECT&lt;/span&gt; dbo&lt;span style="color: rgb(128,128,128)"&gt;.&lt;/span&gt;CosineSimilarity&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;@firstword&lt;span style="color: rgb(128,128,128)"&gt;,&lt;/span&gt; @secondword&lt;span style="color: rgb(128,128,128)"&gt;),&lt;/span&gt; &lt;span style="color: rgb(255,0,0)"&gt;'CosineSimilarity'
&lt;/span&gt;    &lt;span style="color: rgb(0,0,255)"&gt;UNION&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;SELECT&lt;/span&gt; dbo&lt;span style="color: rgb(128,128,128)"&gt;.&lt;/span&gt;DiceSimilarity&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;@firstword&lt;span style="color: rgb(128,128,128)"&gt;,&lt;/span&gt; @secondword&lt;span style="color: rgb(128,128,128)"&gt;),&lt;/span&gt; &lt;span style="color: rgb(255,0,0)"&gt;'DiceSimilarity'
&lt;/span&gt;    &lt;span style="color: rgb(0,0,255)"&gt;UNION&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;SELECT&lt;/span&gt; dbo&lt;span style="color: rgb(128,128,128)"&gt;.&lt;/span&gt;EuclideanDistance&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;@firstword&lt;span style="color: rgb(128,128,128)"&gt;,&lt;/span&gt; @secondword&lt;span style="color: rgb(128,128,128)"&gt;),&lt;/span&gt; &lt;span style="color: rgb(255,0,0)"&gt;'EuclideanDistance'
&lt;/span&gt;    &lt;span style="color: rgb(0,0,255)"&gt;UNION&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;SELECT&lt;/span&gt; dbo&lt;span style="color: rgb(128,128,128)"&gt;.&lt;/span&gt;JaccardSimilarity&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;@firstword&lt;span style="color: rgb(128,128,128)"&gt;,&lt;/span&gt; @secondword&lt;span style="color: rgb(128,128,128)"&gt;),&lt;/span&gt; &lt;span style="color: rgb(255,0,0)"&gt;'JaccardSimilarity'&lt;/span&gt; 
    &lt;span style="color: rgb(0,0,255)"&gt;UNION&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;SELECT&lt;/span&gt; dbo&lt;span style="color: rgb(128,128,128)"&gt;.&lt;/span&gt;Levenstein&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;@firstword&lt;span style="color: rgb(128,128,128)"&gt;,&lt;/span&gt; @secondword&lt;span style="color: rgb(128,128,128)"&gt;),&lt;/span&gt; &lt;span style="color: rgb(255,0,0)"&gt;'Levenstein'
&lt;/span&gt;    &lt;span style="color: rgb(0,0,255)"&gt;UNION&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;SELECT&lt;/span&gt; dbo&lt;span style="color: rgb(128,128,128)"&gt;.&lt;/span&gt;MatchingCoefficient&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;@firstword&lt;span style="color: rgb(128,128,128)"&gt;,&lt;/span&gt; @secondword&lt;span style="color: rgb(128,128,128)"&gt;),&lt;/span&gt; &lt;span style="color: rgb(255,0,0)"&gt;'MatchingCoefficient'
&lt;/span&gt;    &lt;span style="color: rgb(0,0,255)"&gt;UNION&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;SELECT&lt;/span&gt; dbo&lt;span style="color: rgb(128,128,128)"&gt;.&lt;/span&gt;MongeElkan&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;@firstword&lt;span style="color: rgb(128,128,128)"&gt;,&lt;/span&gt; @secondword&lt;span style="color: rgb(128,128,128)"&gt;),&lt;/span&gt; &lt;span style="color: rgb(255,0,0)"&gt;'MongeElkan'
&lt;/span&gt;    &lt;span style="color: rgb(0,0,255)"&gt;UNION&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;SELECT&lt;/span&gt; dbo&lt;span style="color: rgb(128,128,128)"&gt;.&lt;/span&gt;NeedlemanWunch&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;@firstword&lt;span style="color: rgb(128,128,128)"&gt;,&lt;/span&gt; @secondword&lt;span style="color: rgb(128,128,128)"&gt;),&lt;/span&gt; &lt;span style="color: rgb(255,0,0)"&gt;'NeedlemanWunch'
&lt;/span&gt;    &lt;span style="color: rgb(0,0,255)"&gt;UNION&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;SELECT&lt;/span&gt; dbo&lt;span style="color: rgb(128,128,128)"&gt;.&lt;/span&gt;OverlapCoefficient&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;@firstword&lt;span style="color: rgb(128,128,128)"&gt;,&lt;/span&gt; @secondword&lt;span style="color: rgb(128,128,128)"&gt;),&lt;/span&gt; &lt;span style="color: rgb(255,0,0)"&gt;'OverlapCoefficient'
&lt;/span&gt;    &lt;span style="color: rgb(0,0,255)"&gt;UNION&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;SELECT&lt;/span&gt; dbo&lt;span style="color: rgb(128,128,128)"&gt;.&lt;/span&gt;QGramsDistance&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;@firstword&lt;span style="color: rgb(128,128,128)"&gt;,&lt;/span&gt; @secondword&lt;span style="color: rgb(128,128,128)"&gt;),&lt;/span&gt; &lt;span style="color: rgb(255,0,0)"&gt;'QGramsDistance'
&lt;/span&gt;    &lt;span style="color: rgb(0,0,255)"&gt;UNION&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;SELECT&lt;/span&gt; dbo&lt;span style="color: rgb(128,128,128)"&gt;.&lt;/span&gt;SmithWaterman&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;@firstword&lt;span style="color: rgb(128,128,128)"&gt;,&lt;/span&gt; @secondword&lt;span style="color: rgb(128,128,128)"&gt;),&lt;/span&gt; &lt;span style="color: rgb(255,0,0)"&gt;'SmithWaterman'
&lt;/span&gt;    &lt;span style="color: rgb(0,0,255)"&gt;UNION&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;SELECT&lt;/span&gt; dbo&lt;span style="color: rgb(128,128,128)"&gt;.&lt;/span&gt;SmithWatermanGotoh&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;@firstword&lt;span style="color: rgb(128,128,128)"&gt;,&lt;/span&gt; @secondword&lt;span style="color: rgb(128,128,128)"&gt;),&lt;/span&gt; &lt;span style="color: rgb(255,0,0)"&gt;'SmithWatermanGotoh'
&lt;/span&gt;    &lt;span style="color: rgb(0,0,255)"&gt;UNION&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;SELECT&lt;/span&gt; dbo&lt;span style="color: rgb(128,128,128)"&gt;.&lt;/span&gt;SmithWatermanGotohWindowedAffine&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;@firstword&lt;span style="color: rgb(128,128,128)"&gt;,&lt;/span&gt; @secondword&lt;span style="color: rgb(128,128,128)"&gt;),&lt;/span&gt; &lt;span style="color: rgb(255,0,0)"&gt;'SmithWatermanGotohWindowedAffine'
&lt;/span&gt;&lt;span style="color: rgb(128,128,128)"&gt;)&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;This means that now we can easily evaluate the performance and the accuracy of each metric by running queries like:&lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: rgb(0,0,255)"&gt;Select&lt;/span&gt; &lt;span style="color: rgb(128,128,128)"&gt;*&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;from&lt;/span&gt; CompareStringMetrics&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt;'Loyds'&lt;/span&gt;&lt;span style="color: rgb(128,128,128)"&gt;,&lt;/span&gt; &lt;span style="color: rgb(255,0,0)"&gt;'LLoyds'&lt;/span&gt;&lt;span style="color: rgb(128,128,128)"&gt;)&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;where&lt;/span&gt; score &lt;span style="color: rgb(128,128,128)"&gt;&amp;gt;&lt;/span&gt; 0.6
&lt;span style="color: rgb(0,0,255)"&gt;Select&lt;/span&gt; &lt;span style="color: rgb(128,128,128)"&gt;*&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;from&lt;/span&gt; CompareStringMetrics&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt;'bristol'&lt;/span&gt;&lt;span style="color: rgb(128,128,128)"&gt;,&lt;/span&gt; &lt;span style="color: rgb(255,0,0)"&gt;'brighton'&lt;/span&gt;&lt;span style="color: rgb(128,128,128)"&gt;)&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;where&lt;/span&gt; score &lt;span style="color: rgb(128,128,128)"&gt;&amp;lt;&lt;/span&gt; 0.5&lt;/pre&gt;
&lt;p&gt;&lt;a href="http://anastasiosyal.com/images/anastasiosyal_com/WindowsLiveWriter/BeyondSoundExFuzzyGroupingFunctionsforMS_F0CE/image_8.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="239" alt="String Metric Comparison" src="http://anastasiosyal.com/images/anastasiosyal_com/WindowsLiveWriter/BeyondSoundExFuzzyGroupingFunctionsforMS_F0CE/image_thumb_3.png" width="244" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Try out various functions on large database tables, the performance is great! &lt;/p&gt;
&lt;h3&gt;5. Conclusion&lt;a name="conclusion"&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;SimMetrics is a great library for fuzzy text comparisons. This article showed you how you can bring its power into Sql Server. There are plenty of functions to choose from, experiment and see what works best for you. You can be creative on what you want to apply your metric on, e.g  Instead of applying directly on a field you can choose to make simple searchkeys by lower casing fields, striping common text patterns that you dont need (eg Inc, Ltd etc) and removing numbers. There are many ways to apply these sort of functions, what is more suitable for you is your call, since it depends on the context of your problem. If you find any innovative ways of correlating your data share it with us!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;source code: &lt;/strong&gt;(including sql install and uninstall scripts)&lt;br /&gt;&lt;a href="/code/TextFunctions.zip"&gt;TextFunctions.zip&lt;/a&gt;&lt;/p&gt;&lt;img src="http://anastasiosyal.com/aggbug/18.aspx" width="1" height="1" /&gt;&lt;img src="http://feeds.feedburner.com/~r/anastasiosyal/~4/nwLtpNsf5Rw" height="1" width="1"/&gt;</description>
            <dc:creator>Anastasios Yalanopoulos</dc:creator>
            <guid>http://anastasiosyal.com/archive/2009/01/11/18.aspx</guid>
            <pubDate>Sun, 11 Jan 2009 00:08:42 GMT</pubDate>
            <wfw:comment>http://anastasiosyal.com/comments/18.aspx</wfw:comment>
            <comments>http://anastasiosyal.com/archive/2009/01/11/18.aspx#feedback</comments>
            <slash:comments>10</slash:comments>
            <wfw:commentRss>http://anastasiosyal.com/comments/commentRss/18.aspx</wfw:commentRss>
        </item>
        <item>
            <title>SQL Server script to auto-create indexes on all Foreign Key Columns</title>
            <category>SQL</category>
            <link>http://anastasiosyal.com/archive/2008/07/29/sql-server-script-to-auto-create-indexes-on-all-foreign-key.aspx</link>
            <description>&lt;p&gt;If you want a quick way to set some default indexes up in your database the best candidates for your indexes would be the foreign keys. They are usually highly selective and many of our queries tend to have some sort of filter on the foreign keys, this makes them good candidates for an index. &lt;/p&gt;
&lt;p&gt;You may be quick to think:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;'but sql server has indexes on the foreign keys'&lt;/em&gt; &lt;/p&gt;
&lt;p&gt;That's not true, since a foreign key is an integrity constraint while an index is for performance. Have a look at an interesting discussion over at sqlblog about this: &lt;a href="http://sqlblog.com/blogs/greg_low/archive/2008/07/29/indexing-foreign-keys-should-sql-server-do-that-automatically.aspx" title="http://sqlblog.com/blogs/greg_low/archive/2008/07/29/indexing-foreign-keys-should-sql-server-do-that-automatically.aspx"&gt;http://sqlblog.com/blogs/greg_low/archive/2008/07/29/indexing-foreign-keys-should-sql-server-do-that-automatically.aspx&lt;/a&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;The following SQL Script will create a non clustered index on each of the foreign key columns in our database. &lt;/p&gt;
&lt;pre class="code"&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;--Create non clustered indexes for all foreign key references in the database&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;DECLARE&lt;/span&gt; @sql &lt;span style="color: rgb(0, 0, 255);"&gt;nvarchar&lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(255, 0, 255);"&gt;max&lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;)&lt;/span&gt; &lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;SELECT&lt;/span&gt; @sql &lt;span style="color: rgb(128, 128, 128);"&gt;=&lt;/span&gt; &lt;span style="color: rgb(255, 0, 255);"&gt;IsNull&lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;(&lt;/span&gt;@sql &lt;span style="color: rgb(128, 128, 128);"&gt;+&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;';'&lt;/span&gt; &lt;span style="color: rgb(128, 128, 128);"&gt;+&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;char&lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;(&lt;/span&gt;13&lt;span style="color: rgb(128, 128, 128);"&gt;)&lt;/span&gt; &lt;span style="color: rgb(128, 128, 128);"&gt;,&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;''&lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;)&lt;/span&gt; &lt;span style="color: rgb(128, 128, 128);"&gt;+&lt;/span&gt;  &lt;span style="color: rgb(255, 0, 0);"&gt;'CREATE NONCLUSTERED INDEX [IX_'&lt;/span&gt; &lt;span style="color: rgb(128, 128, 128);"&gt;+&lt;/span&gt; tablename &lt;span style="color: rgb(128, 128, 128);"&gt;+&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;'_'&lt;/span&gt; &lt;span style="color: rgb(128, 128, 128);"&gt;+&lt;/span&gt; columnname &lt;span style="color: rgb(128, 128, 128);"&gt;+&lt;/span&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;'] ON [dbo].['&lt;/span&gt; &lt;span style="color: rgb(128, 128, 128);"&gt;+&lt;/span&gt; tablename &lt;span style="color: rgb(128, 128, 128);"&gt;+&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;'] ( ['&lt;/span&gt; &lt;span style="color: rgb(128, 128, 128);"&gt;+&lt;/span&gt; columnname &lt;span style="color: rgb(128, 128, 128);"&gt;+&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;'] ASC)'&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;FROM&lt;/span&gt; &lt;br /&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;(&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;--Script all foreign key columns that are not already an index &lt;/span&gt; &lt;/span&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;SELECT&lt;br /&gt;&lt;/span&gt;        o&lt;span style="color: rgb(128, 128, 128);"&gt;.&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;name&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;AS&lt;/span&gt; tablename&lt;span style="color: rgb(128, 128, 128);"&gt;,&lt;/span&gt; cols&lt;span style="color: rgb(128, 128, 128);"&gt;.&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;name&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;AS&lt;/span&gt; columnName &lt;span style="color: rgb(0, 0, 255);"&gt;FROM&lt;/span&gt; &lt;span style="color: rgb(0, 128, 0);"&gt;sys.foreign_key_columns&lt;/span&gt; fc&lt;br /&gt;        &lt;span style="color: rgb(128, 128, 128);"&gt;inner&lt;/span&gt; &lt;span style="color: rgb(128, 128, 128);"&gt;join&lt;/span&gt; &lt;span style="color: rgb(0, 128, 0);"&gt;sys.objects&lt;/span&gt; o &lt;span style="color: rgb(0, 0, 255);"&gt;on&lt;/span&gt; fc&lt;span style="color: rgb(128, 128, 128);"&gt;.&lt;/span&gt;parent_object_id &lt;span style="color: rgb(128, 128, 128);"&gt;=&lt;/span&gt; o&lt;span style="color: rgb(128, 128, 128);"&gt;.&lt;/span&gt;&lt;span style="color: rgb(255, 0, 255);"&gt;object_id&lt;br /&gt;&lt;/span&gt;        &lt;span style="color: rgb(128, 128, 128);"&gt;inner&lt;/span&gt; &lt;span style="color: rgb(128, 128, 128);"&gt;join&lt;/span&gt; &lt;span style="color: rgb(0, 128, 0);"&gt;sys.columns&lt;/span&gt; cols &lt;span style="color: rgb(0, 0, 255);"&gt;on&lt;/span&gt; cols&lt;span style="color: rgb(128, 128, 128);"&gt;.&lt;/span&gt;&lt;span style="color: rgb(255, 0, 255);"&gt;object_id&lt;/span&gt; &lt;span style="color: rgb(128, 128, 128);"&gt;=&lt;/span&gt; o&lt;span style="color: rgb(128, 128, 128);"&gt;.&lt;/span&gt;&lt;span style="color: rgb(255, 0, 255);"&gt;object_id&lt;/span&gt; &lt;span style="color: rgb(128, 128, 128);"&gt;and&lt;/span&gt; fc&lt;span style="color: rgb(128, 128, 128);"&gt;.&lt;/span&gt;parent_column_id &lt;span style="color: rgb(128, 128, 128);"&gt;=&lt;/span&gt; cols&lt;span style="color: rgb(128, 128, 128);"&gt;.&lt;/span&gt;column_id&lt;br /&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;EXCEPT&lt;/span&gt; &lt;br /&gt;        &lt;span style="color: rgb(0, 0, 255);"&gt;SELECT&lt;/span&gt; o&lt;span style="color: rgb(128, 128, 128);"&gt;.&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;name&lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;,&lt;/span&gt; cols&lt;span style="color: rgb(128, 128, 128);"&gt;.&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;name&lt;/span&gt;  &lt;span style="color: rgb(0, 0, 255);"&gt;FROM&lt;/span&gt; &lt;span style="color: rgb(0, 128, 0);"&gt;sys.index_columns&lt;/span&gt; icols&lt;br /&gt;            &lt;span style="color: rgb(128, 128, 128);"&gt;inner&lt;/span&gt; &lt;span style="color: rgb(128, 128, 128);"&gt;join&lt;/span&gt; &lt;span style="color: rgb(0, 128, 0);"&gt;sys.objects&lt;/span&gt; o &lt;span style="color: rgb(0, 0, 255);"&gt;on&lt;/span&gt; icols&lt;span style="color: rgb(128, 128, 128);"&gt;.&lt;/span&gt;&lt;span style="color: rgb(255, 0, 255);"&gt;object_Id&lt;/span&gt; &lt;span style="color: rgb(128, 128, 128);"&gt;=&lt;/span&gt; o&lt;span style="color: rgb(128, 128, 128);"&gt;.&lt;/span&gt;&lt;span style="color: rgb(255, 0, 255);"&gt;object_id&lt;br /&gt;&lt;/span&gt;            &lt;span style="color: rgb(128, 128, 128);"&gt;inner&lt;/span&gt; &lt;span style="color: rgb(128, 128, 128);"&gt;join&lt;/span&gt; &lt;span style="color: rgb(0, 128, 0);"&gt;sys.columns&lt;/span&gt; cols &lt;span style="color: rgb(0, 0, 255);"&gt;on&lt;/span&gt; cols&lt;span style="color: rgb(128, 128, 128);"&gt;.&lt;/span&gt;&lt;span style="color: rgb(255, 0, 255);"&gt;object_id&lt;/span&gt; &lt;span style="color: rgb(128, 128, 128);"&gt;=&lt;/span&gt; o&lt;span style="color: rgb(128, 128, 128);"&gt;.&lt;/span&gt;&lt;span style="color: rgb(255, 0, 255);"&gt;object_id&lt;/span&gt; &lt;span style="color: rgb(128, 128, 128);"&gt;and&lt;/span&gt; icols&lt;span style="color: rgb(128, 128, 128);"&gt;.&lt;/span&gt;column_id &lt;span style="color: rgb(128, 128, 128);"&gt;=&lt;/span&gt; cols&lt;span style="color: rgb(128, 128, 128);"&gt;.&lt;/span&gt;column_id&lt;br /&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;)&lt;/span&gt; T&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;ORDER&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;BY&lt;/span&gt; &lt;br /&gt;    tablename&lt;span style="color: rgb(128, 128, 128);"&gt;,&lt;/span&gt; &lt;br /&gt;    columnname&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;--Display the sql that will be executed&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;Print&lt;/span&gt; @sql &lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;--Run the sql and create all the indexes&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;exec&lt;/span&gt; &lt;span style="color: rgb(128, 0, 0);"&gt;sp_executesql&lt;/span&gt; @sql&lt;/pre&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;To monitor the performance of your existing indexes &lt;a href="http://www.karaszi.com/SQLServer/util_sp_indexinfo.asp"&gt;check out the script sp_indexInfo by Tibor Karaszi&lt;/a&gt;.     &lt;br /&gt;
It is a stored procedure that provides some useful metrics for all the indexes in a given table or in a given database. &lt;/p&gt;&lt;img src="http://anastasiosyal.com/aggbug/17.aspx" width="1" height="1" /&gt;&lt;img src="http://feeds.feedburner.com/~r/anastasiosyal/~4/oO9RYwLWVtI" height="1" width="1"/&gt;</description>
            <dc:creator>Anastasios Yalanopoulos</dc:creator>
            <guid>http://anastasiosyal.com/archive/2008/07/29/sql-server-script-to-auto-create-indexes-on-all-foreign-key.aspx</guid>
            <pubDate>Tue, 29 Jul 2008 22:38:52 GMT</pubDate>
            <wfw:comment>http://anastasiosyal.com/comments/17.aspx</wfw:comment>
            <comments>http://anastasiosyal.com/archive/2008/07/29/sql-server-script-to-auto-create-indexes-on-all-foreign-key.aspx#feedback</comments>
            <slash:comments>1</slash:comments>
            <wfw:commentRss>http://anastasiosyal.com/comments/commentRss/17.aspx</wfw:commentRss>
        </item>
        <item>
            <title>4 Features for C# 4.0</title>
            <link>http://anastasiosyal.com/archive/2008/07/19/4-features-for-c-4.0.aspx</link>
            <description>&lt;p&gt;Plenty of &lt;a href="http://msdn.microsoft.com/en-us/library/bb308966.aspx"&gt;powerful new language features&lt;/a&gt; have fairly recently become mainstream with the launch of VS 2008 in Nov 2007 that supports C# 3.0, amongst which:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Implicitly Typed Local Variables &lt;/li&gt;    &lt;li&gt;Extension Methods &lt;/li&gt;    &lt;li&gt;Lambda Expressions &lt;/li&gt;    &lt;li&gt;Object and Collection Initializers &lt;/li&gt;    &lt;li&gt;Anonymous Types &lt;/li&gt;    &lt;li&gt;Query Expressions &lt;/li&gt;    &lt;li&gt;Automatically Implemented Properties &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Although most of us are still trying to fully absorb the above features, there has been some speculation going on about what sort of features we would like to see in the next version of C# and &lt;a href="http://codebetter.com/blogs/jeremy.miller/archive/2007/11/25/what-do-you-want-in-c-vnext.aspx"&gt;Jeremy Miller has posted a question&lt;/a&gt; with what he would like to see. &lt;/p&gt;  &lt;p&gt;Here are some of the language features I would really like to see in C#:&lt;/p&gt;  &lt;h3&gt;1. Implementing Interfaces by delegation to fields&lt;/h3&gt;  &lt;p&gt;I would like to see support in C# 4.0 that would allow us to delegate the implementation of an interface to a field in the implementing class. For example this could look something like the following: &lt;/p&gt;  &lt;pre class="code"&gt;    &lt;span style="color: rgb(0,128,0)"&gt;//faux code
&lt;/span&gt;    &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;class&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;Foo&lt;/span&gt; : &lt;span style="color: rgb(43,145,175)"&gt;IList&amp;lt;&lt;span style="color: rgb(0,0,255)"&gt;string&lt;/span&gt;&amp;gt;
&lt;/span&gt;    {
        &lt;span style="color: rgb(0,0,255)"&gt;private &lt;/span&gt;&lt;span style="color: rgb(43,145,175)"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: rgb(0,0,255)"&gt;string&lt;/span&gt;&amp;gt; _Collection &lt;span style="color: rgb(0,0,255)"&gt;implements &lt;/span&gt;&lt;span style="color: rgb(43,145,175)"&gt;IList&amp;lt;&lt;span style="color: rgb(0,0,255)"&gt;string&lt;/span&gt;&amp;gt;&lt;/span&gt;;

        &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; Foo()
        {
            _Collection = &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: rgb(0,0,255)"&gt;string&lt;/span&gt;&amp;gt;();
        }
    }&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;The field could be delegated to implement one or more interfaces from the encapsulating class by separating them with a comma. This would remove a lot of redundant code in scenarios like the above one, ie. Instead of implementing a lot of pass through functions on the encapsulating class (Foo) the functions are directly mapped to the delegated interface implementation. This sort of functionality would also enhance support for &lt;a href="http://en.wikipedia.org/wiki/Mixin"&gt;mixins&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;This is known as the &lt;a href="http://en.wikipedia.org/wiki/Delegation_pattern"&gt;delegation pattern&lt;/a&gt; and from wikipedia: &lt;/p&gt;

&lt;blockquote&gt;The delegation pattern is a technique where an object outwardly expresses certain behaviour but in reality delegates responsibility for implementing that behaviour to an associated object in an Inversion of Responsibility. The delegation pattern is the fundamental abstraction that underpins composition (also referred to as aggregation), mixins and aspects.&lt;/blockquote&gt;

&lt;p&gt;Taking it one step even further, one could override the delegated implementation in a syntax like so: &lt;/p&gt;

&lt;pre class="code"&gt;    &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;class&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;Foo&lt;/span&gt; : &lt;span style="color: rgb(43,145,175)"&gt;IList&lt;/span&gt;&amp;lt;&lt;span style="color: rgb(0,0,255)"&gt;string&lt;/span&gt;&amp;gt;
    {
        &lt;span style="color: rgb(0,0,255)"&gt;private &lt;/span&gt;&lt;span style="color: rgb(43,145,175)"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: rgb(0,0,255)"&gt;string&lt;/span&gt;&amp;gt; _Collection { &lt;span style="color: rgb(0,0,255)"&gt;get&lt;/span&gt;; &lt;span style="color: rgb(0,0,255)"&gt;set&lt;/span&gt;; } &lt;span style="color: rgb(0,0,255)"&gt;implements &lt;/span&gt;&lt;span style="color: rgb(43,145,175)"&gt;IList&amp;lt;&lt;span style="color: rgb(0,0,255)"&gt;string&lt;/span&gt;&amp;gt;&lt;/span&gt;;

        &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; Foo()
        {
            _Collection = &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: rgb(0,0,255)"&gt;string&lt;/span&gt;&amp;gt;();
        }

        &lt;strong&gt;&lt;span style="color: rgb(0,128,0)"&gt;//This would override the delegated implementation 
&lt;/span&gt;        &lt;/strong&gt;&lt;span style="color: rgb(0,128,0)"&gt;&lt;strong&gt;// for nice mixin functionality and easy decorator pattern implementation&lt;/strong&gt;
&lt;/span&gt;        &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;int&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;IList&lt;/span&gt;.Add(&lt;span style="color: rgb(0,0,255)"&gt;string&lt;/span&gt; value)
        {
            &lt;span style="color: rgb(0,0,255)"&gt;if&lt;/span&gt; (!_Collection.Contains(value))
                _Collection.Add(value);
        }
    }&lt;/pre&gt;

&lt;h3&gt;2. Anonymous type return values&lt;/h3&gt;

&lt;p&gt;I would like to see the anonymous types becoming first class 'citizens' in C#. Anonymous types can only be used in a local scope and &lt;a title="Anonymous type support is incomplete in C# 3.0" href="http://anastasiosyal.com/archive/2007/11/27/c-3.0-anonymous-type-support-is-incomplete.aspx"&gt;cannot be returned from functions&lt;/a&gt;. It would be nice if we could return our strongly typed Linq Query Projection from a function eg:&lt;/p&gt;

&lt;pre class="code"&gt;        &lt;span style="color: rgb(0,128,0)"&gt;//faux code
&lt;/span&gt;        &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;var&lt;/span&gt; GetProductInfos()
        {
            &lt;span style="color: rgb(0,0,255)"&gt;var&lt;/span&gt; productInfos =
                &lt;span style="color: rgb(0,0,255)"&gt;from&lt;/span&gt; p &lt;span style="color: rgb(0,0,255)"&gt;in&lt;/span&gt; products
                &lt;span style="color: rgb(0,0,255)"&gt;select&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; { p.ProductName, p.Category, Price = p.UnitPrice };

            &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; productInfos;
        }&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt; &lt;/p&gt;

&lt;h3&gt;3. Some Duck-typing or Structural Subtyping support&lt;/h3&gt;

&lt;p&gt;If a class has a property or a method signature that is the same as the method signature on a declared interface, then that class implicitly implements that interface, if it is not already inheriting from it.  The class would implicitly implement an interface if and only if it would implement all the method signatures of a given interface. Basically &lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;if it walks like a duck and it quacks like a duck, then I would call it a duck! (James Riley)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So what is the difference with &lt;a href="http://en.wikipedia.org/wiki/Structural_type_system"&gt;Structural Subtyping&lt;/a&gt;? I would argue that structural subtyping is more suitable to the static style of C#, since it is a &lt;em&gt;'static duck typing'&lt;/em&gt;, or according to wikipedia:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Duck typing differs from structural typing in that only the part of the structure accessed at run time is checked for compatibility.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Lets see how this could be beneficial through a use case:&lt;/p&gt;

&lt;p&gt;The .Net framework has a few controls that implement a ReadOnly property amongst which are the TextBox, DataGrid, NumericUpDown. &lt;/p&gt;

&lt;p&gt;Lets define the IReadOnlyRestrictable interface in our source like so:&lt;/p&gt;

&lt;pre class="code"&gt;        &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;interface&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;IReadOnlyRestricable
&lt;/span&gt;        {
            &lt;span style="color: rgb(0,0,255)"&gt;bool&lt;/span&gt; ReadOnly { &lt;span style="color: rgb(0,0,255)"&gt;get&lt;/span&gt;; &lt;span style="color: rgb(0,0,255)"&gt;set&lt;/span&gt;; }
        }&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;
  &lt;br /&gt;Let's assume that we wanted to Loop through all the controls on a form and anything that satisfies the above interface signature (i.e has a property 'ReadOnly') set its readonly property to true. With ducktyping the qualifying controls would be cast to a valid IReadOnlyRestrictable instance like below, without needing to resort to reflection&lt;/p&gt;

&lt;pre class="code"&gt;        &lt;span style="color: rgb(0,0,255)"&gt;foreach&lt;/span&gt; (&lt;span style="color: rgb(43,145,175)"&gt;Control&lt;/span&gt; c &lt;span style="color: rgb(0,0,255)"&gt;in&lt;/span&gt; f.Controls)
        {
            &lt;span style="color: rgb(0,128,0)"&gt;//would like to have implicit cast to IReadOnlyRestrictable if interface contract is in class we are checking against
&lt;/span&gt;            &lt;span style="color: rgb(43,145,175)"&gt;IReadOnlyRestricable&lt;/span&gt; editable = c &lt;span style="color: rgb(0,0,255)"&gt;as&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;IReadOnlyRestricable&lt;/span&gt;; 
            &lt;span style="color: rgb(0,0,255)"&gt;if&lt;/span&gt; (editable != &lt;span style="color: rgb(0,0,255)"&gt;null&lt;/span&gt;)
                editable.ReadOnly = &lt;span style="color: rgb(0,0,255)"&gt;true&lt;/span&gt;;
        }&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;The main advantage I see with ducktyping is that you can declare interfaces for libraries that you do not have access to, this can be useful in scenarios where you would like to minimise dependancies, check out &lt;a href="http://haacked.com/archive/2007/08/19/why-duck-typing-matters-to-c-developers.aspx"&gt;Phil Haacks more extensive post on duck typing&lt;/a&gt; and why he believes it would benefit C# developers. &lt;/p&gt;

&lt;p&gt;Apparantly, the c# foreach operator already uses duck typing according to &lt;a href="http://blogs.msdn.com/kcwalina/archive/2007/07/18/DuckNotation.aspx"&gt;Krzysztof Cwalina&lt;/a&gt;&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;h3&gt;4. Safe Null Dereferencing Operator&lt;/h3&gt;

&lt;p&gt;I would really like to see a safe way to dereference a null value in an expression that of form Object.Property.Property.Value.&lt;/p&gt;

&lt;p&gt;For example if we had Customer?.FirstName and Customer was null, then the expression would evaluate to null instead of raising a null reference exception. 
  &lt;br /&gt;Some more examples of how this could work: &lt;/p&gt;

&lt;pre class="code"&gt;    &lt;span style="color: rgb(0,128,0)"&gt;//FAUX CODE
&lt;/span&gt;    &lt;span style="color: rgb(0,128,0)"&gt;//this would throw a null reference exception as usual if either Customer or Order was null
&lt;/span&gt;    &lt;span style="color: rgb(0,0,255)"&gt;int&lt;/span&gt; orderNumber = Customer.Order.OrderNumber;

    &lt;span style="color: rgb(0,128,0)"&gt;//this would not compile since it would require a nullable return type
&lt;/span&gt;    &lt;span style="color: rgb(0,0,255)"&gt;int&lt;/span&gt; orderNumber = Customer.Order?.OrderNumber;

    &lt;span style="color: rgb(0,128,0)"&gt;//this would return null if a Customer was null or if Order was null 
&lt;/span&gt;    &lt;span style="color: rgb(0,0,255)"&gt;int&lt;/span&gt;? orderNumber = Customer?.Order?.OrderNumber;
    &lt;span style="color: rgb(0,0,255)"&gt;if&lt;/span&gt; (orderNumber.HasValue) 
        &lt;span style="color: rgb(0,128,0)"&gt;//... do something with it

&lt;/span&gt;    &lt;span style="color: rgb(0,128,0)"&gt;//instead of having to do 
&lt;/span&gt;    &lt;span style="color: rgb(0,0,255)"&gt;if&lt;/span&gt; ((Customer != &lt;span style="color: rgb(0,0,255)"&gt;null&lt;/span&gt;) &amp;amp;&amp;amp; (Customer.Order != &lt;span style="color: rgb(0,0,255)"&gt;null&lt;/span&gt;))
        int a = Customer.Order.OrderNumber&lt;/pre&gt;

&lt;p&gt; &lt;/p&gt;

&lt;h3&gt;Wrap up&lt;/h3&gt;

&lt;p&gt;Here is a &lt;a href="http://channel9.msdn.com/posts/Charles/C-40-Meet-the-Design-Team/"&gt;recent interview of the C# 4.0 team&lt;/a&gt; in the room where all the magic happens&lt;/p&gt;

&lt;p&gt;What is your take? Do you agree? What features you would like to see? &lt;/p&gt;&lt;img src="http://anastasiosyal.com/aggbug/16.aspx" width="1" height="1" /&gt;&lt;img src="http://feeds.feedburner.com/~r/anastasiosyal/~4/vy3L-CdB8Eo" height="1" width="1"/&gt;</description>
            <dc:creator>Anastasios Yalanopoulos</dc:creator>
            <guid>http://anastasiosyal.com/archive/2008/07/19/4-features-for-c-4.0.aspx</guid>
            <pubDate>Sat, 19 Jul 2008 00:26:34 GMT</pubDate>
            <wfw:comment>http://anastasiosyal.com/comments/16.aspx</wfw:comment>
            <comments>http://anastasiosyal.com/archive/2008/07/19/4-features-for-c-4.0.aspx#feedback</comments>
            <slash:comments>36</slash:comments>
            <wfw:commentRss>http://anastasiosyal.com/comments/commentRss/16.aspx</wfw:commentRss>
        </item>
        <item>
            <title>SQL CLR without DLL dependency for your production server</title>
            <category>SQL</category>
            <category>SQLCLR</category>
            <link>http://anastasiosyal.com/archive/2008/07/17/sql-clr-without-dll-dependency-for-your-production-server.aspx</link>
            <description>&lt;p&gt;Have you been shying out of putting extra functions on your SQL Server 2005 using SQL CLR simply because you would like to avoid DLL Hell?!&lt;/p&gt;  &lt;p&gt;Well, the good news is that you need not be so worried, since SQL Server does not link to the dll itself, but instead it embeds the assembly in the database. What's even better is that you can deploy your assembly by simply scripting it. &lt;/p&gt;  &lt;p&gt;Lets do this with an example, in the &lt;a href="http://anastasiosyal.com/archive/2008/07/05/regular-expressions-in-ms-sql-server-using-clr.aspx"&gt;previous post&lt;/a&gt; there is a sample that shows how to create support for regular expressions using SQL CLR. To deploy this on your production server without having to copy any url's you simply need to open Sql Server Management Studio and go to:     &lt;br /&gt;DB &amp;gt; Programmability &amp;gt; Assemblies &amp;gt; AssemblyName &amp;gt; RightClick &amp;gt; ScriptAssembly As &amp;gt; Create To &amp;gt; Clipboard | File | New Window&lt;/p&gt;  &lt;p&gt;like so: &lt;/p&gt;  &lt;p&gt;&lt;a href="http://anastasiosyal.com/images/anastasiosyal_com/WindowsLiveWriter/SQLCLRwithoutDLLdependencyforyourproduct_120E9/image_2.png"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="267" alt="image" src="http://anastasiosyal.com/images/anastasiosyal_com/WindowsLiveWriter/SQLCLRwithoutDLLdependencyforyourproduct_120E9/image_thumb.png" width="535" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;In fact this will create the following sql script for you: &lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: rgb(0,0,255)"&gt;CREATE&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;ASSEMBLY&lt;/span&gt; [TextFunctions]
&lt;span style="color: rgb(0,0,255)"&gt;AUTHORIZATION&lt;/span&gt; [dbo]
&lt;span style="color: rgb(0,0,255)"&gt;FROM&lt;/span&gt; 0x4D5A90000300000004000000FFFF0000B800000000000000400000000000000000000000000000000000000000000000000000000000000000000000800000000E1FBA0E00B409CD21B8014CCD21546869732070726F6772616D2063616E6E6F742062652072756E20696E20444F53206D6F64652E0D0D0A2400000000000000504500004C010300C5987F480000000000000000E0000E210B0108000010000000200000000000000E290000002000000040000000004000002000000010000004000000000000000400000000000000008000000010000000000000030040050000100000100000000010000010000000000000100000000000000000000000C02800004B000000004000002803000000000000000000000000000000000000006000000C000000442800001C0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000080000000000000000000000082000004800000000000000000000002E7465787400000014090000002000000010000000100000000000000000000000000000200000602E7273726300000028030000004000000010000000200000000000000000000000000000400000402E72656C6F6300000C00000000600000001000000030000000000000000000000000000040000042000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F0280000000000004800000002000500DC200000680700000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000CA0F00281100000A2D090F01281100000A2C067E1200000A2A0F00281300000A0F01281300000A17281400000A281500000A2A000330040042000000000000000F00281100000A2D120F01281100000A2D090F02281100000A2C067E1600000A2A0F00281300000A0F01281300000A0F02281300000A17281700000A731800000A2A1E02281900000A2A000042534A4201000100000000000C00000076322E302E35303732370000000005006C00000074020000237E0000E00200005403000023537472696E6773000000003406000008000000235553003C0600001000000023475549440000004C0600001C01000023426C6F620000000000000002000001471500000900000000FA0133001600000100000016000000020000000300000005000000190000000F000000010000000300000000000A0001000000000006003F0038000A00670052000A00720052000600AC009A000600C9009A0006000101E20006000F01E200060023019A0006003C019A00060057019A00060072019A0006008B019A000600A4019A000600C3019A000600E0019A0006000A02F70143001E02000006004D022D0206006D022D020A00B40299020E001103F2020E001703F2020000000001000000000001000100010010001C00000005000100010050200000000096007C000A0001008420000000009600870013000300D22000000000861894001E00060000000100C90200000200CF0200000100C90200000200CF02000003003803210094002200290094002200310094002200390094002700410094002200490094002200510094002200590094002200610094002200690094002200710094002200790094002200810094002C00910094003200990094001E00A10094001E001900D7025C001100E20260001900E8026400A9002403680011002C037000190044037600A90049037A00190094002200090094001E002000830037002E004300D8002E000B0083002E001B0090002E002300BA002E003300BA002E003B00C0002E005B00BA002E004B00BA002E005300BA002E006B00EB002E007B00FD002E006300D8002E007300F4004000830037000480000001000000000000000000000000008B02000002000000000000000000000001002F00000000000200000000000000000000000100460000000000020000000000000000000000010038000000000000000000003C4D6F64756C653E005465787446756E6374696F6E732E646C6C00526567756C617245787072657373696F6E73006D73636F726C69620053797374656D004F626A6563740053797374656D2E446174610053797374656D2E446174612E53716C54797065730053716C426F6F6C65616E0053716C537472696E670052656745784D617463680052656745785265706C616365002E63746F720053797374656D2E5265666C656374696F6E00417373656D626C7946696C6556657273696F6E41747472696275746500417373656D626C7956657273696F6E4174747269627574650053797374656D2E52756E74696D652E496E7465726F705365727669636573004775696441747472696275746500436F6D56697369626C6541747472696275746500417373656D626C7943756C7475726541747472696275746500417373656D626C7954726164656D61726B41747472696275746500417373656D626C79436F7079726967687441747472696275746500417373656D626C7950726F6475637441747472696275746500417373656D626C79436F6D70616E7941747472696275746500417373656D626C79436F6E66696775726174696F6E41747472696275746500417373656D626C794465736372697074696F6E41747472696275746500417373656D626C795469746C654174747269627574650053797374656D2E446961676E6F73746963730044656275676761626C6541747472696275746500446562756767696E674D6F6465730053797374656D2E52756E74696D652E436F6D70696C6572536572766963657300436F6D70696C6174696F6E52656C61786174696F6E734174747269627574650052756E74696D65436F6D7061746962696C697479417474726962757465005465787446756E6374696F6E73004D6963726F736F66742E53716C5365727665722E5365727665720053716C46756E6374696F6E41747472696275746500696E707574007061747465726E006765745F49734E756C6C0046616C7365006765745F56616C75650053797374656D2E546578742E526567756C617245787072657373696F6E730052656765780052656765784F7074696F6E730049734D61746368006F705F496D706C69636974007265706C6163656D656E74004E756C6C005265706C616365000000000003200000000000D51DC224975A24449F15285FBFA1D5530008B77A5C561934E0890800021109110D110D0A0003110D110D110D110D03200001042001010E04200101020520010111450420010108240100020054020F497344657465726D696E6973746963015402094973507265636973650103200002030611090320000E070003020E0E11590500011109020306110D0800040E0E0E0E11590C010007312E302E302E3000002901002464313338356464382D376539322D343065362D383234632D646632376639393862656630000005010000000017010012436F7079726967687420C2A920203230303700001201000D5465787446756E6374696F6E7300000801000200000000000801000800000000001E01000100540216577261704E6F6E457863657074696F6E5468726F77730100000000C5987F4800000000020000005F0000006028000060180000525344536A480B33B1CFDD46B12FF5343A6664BF01000000433A5C446576656C6F706D656E745C54657374696E675C434C525C5465787446756E6374696F6E735C6F626A5C52656C656173655C5465787446756E6374696F6E732E7064620000E82800000000000000000000FE280000002000000000000000000000000000000000000000000000F02800000000000000005F436F72446C6C4D61696E006D73636F7265652E646C6C0000000000FF2500204000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100100000001800008000000000000000000000000000000100010000003000008000000000000000000000000000000100000000004800000058400000D00200000000000000000000D00234000000560053005F00560045005200530049004F004E005F0049004E0046004F0000000000BD04EFFE00000100000001000000000000000100000000003F000000000000000400000002000000000000000000000000000000440000000100560061007200460069006C00650049006E0066006F00000000002400040000005400720061006E0073006C006100740069006F006E00000000000000B00430020000010053007400720069006E006700460069006C00650049006E0066006F0000000C020000010030003000300030003000340062003000000044000E000100460069006C0065004400650073006300720069007000740069006F006E00000000005400650078007400460075006E006300740069006F006E0073000000300008000100460069006C006500560065007200730069006F006E000000000031002E0030002E0030002E003000000044001200010049006E007400650072006E0061006C004E0061006D00650000005400650078007400460075006E006300740069006F006E0073002E0064006C006C0000004800120001004C006500670061006C0043006F007000790072006900670068007400000043006F0070007900720069006700680074002000A90020002000320030003000370000004C00120001004F0072006900670069006E0061006C00460069006C0065006E0061006D00650000005400650078007400460075006E006300740069006F006E0073002E0064006C006C0000003C000E000100500072006F0064007500630074004E0061006D006500000000005400650078007400460075006E006300740069006F006E0073000000340008000100500072006F006400750063007400560065007200730069006F006E00000031002E0030002E0030002E003000000038000800010041007300730065006D0062006C0079002000560065007200730069006F006E00000031002E0030002E0030002E0030000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000C0000001039000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
&lt;span style="color: rgb(0,0,255)"&gt;WITH&lt;/span&gt; PERMISSION_SET &lt;span style="color: rgb(128,128,128)"&gt;=&lt;/span&gt; SAFE&lt;/pre&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;Without having the dll nor the requirement to link to any dll you now have part of your change script for deploying this assembly to your production server. &lt;/p&gt;

&lt;p&gt;Of course, the server still needs to be CLR Enabled, if it is not CLR Enabled you will need to enable it before creating the assembly:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: rgb(128,0,0)"&gt;sp_configure&lt;/span&gt; &lt;span style="color: rgb(255,0,0)"&gt;'clr enabled'&lt;/span&gt;&lt;span style="color: rgb(128,128,128)"&gt;,&lt;/span&gt; 1
&lt;span style="color: rgb(0,0,255)"&gt;RECONFIGURE&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;WITH&lt;/span&gt; OVERRIDE&lt;/pre&gt;

&lt;p&gt;Before we can test our assembly we register our new functions&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: rgb(0,0,255)"&gt;CREATE&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Function&lt;/span&gt; RegExMatch&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;@Input &lt;span style="color: rgb(0,0,255)"&gt;NVARCHAR&lt;/span&gt;&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;512&lt;span style="color: rgb(128,128,128)"&gt;),&lt;/span&gt;@Pattern &lt;span style="color: rgb(0,0,255)"&gt;NVARCHAR&lt;/span&gt;&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;127&lt;span style="color: rgb(128,128,128)"&gt;))
&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;RETURNS&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;BIT
EXTERNAL&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;NAME&lt;/span&gt; TextFunctions&lt;span style="color: rgb(128,128,128)"&gt;.&lt;/span&gt;RegularExpressions&lt;span style="color: rgb(128,128,128)"&gt;.&lt;/span&gt;RegExMatch
GO
&lt;span style="color: rgb(0,0,255)"&gt;CREATE&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Function&lt;/span&gt; RegExReplace&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;@Input &lt;span style="color: rgb(0,0,255)"&gt;NVARCHAR&lt;/span&gt;&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;512&lt;span style="color: rgb(128,128,128)"&gt;),&lt;/span&gt;@Pattern &lt;span style="color: rgb(0,0,255)"&gt;NVARCHAR&lt;/span&gt;&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;127&lt;span style="color: rgb(128,128,128)"&gt;),&lt;/span&gt; @Replacement &lt;span style="color: rgb(0,0,255)"&gt;NVARCHAR&lt;/span&gt;&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;512&lt;span style="color: rgb(128,128,128)"&gt;))
&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;RETURNS&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;NVARCHAR&lt;/span&gt;&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;512&lt;span style="color: rgb(128,128,128)"&gt;)
&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;EXTERNAL&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;NAME&lt;/span&gt; TextFunctions&lt;span style="color: rgb(128,128,128)"&gt;.&lt;/span&gt;RegularExpressions&lt;span style="color: rgb(128,128,128)"&gt;.&lt;/span&gt;RegExReplace
GO&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;Now we lets test our newly available functions:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: rgb(0,0,255)"&gt;Select&lt;/span&gt; dbo&lt;span style="color: rgb(128,128,128)"&gt;.&lt;/span&gt;RegExMatch&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt;'333-4444'&lt;/span&gt;&lt;span style="color: rgb(128,128,128)"&gt;,&lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt;'\d{3}-\d{4}'&lt;/span&gt;&lt;span style="color: rgb(128,128,128)"&gt;)
&lt;/span&gt;&lt;span style="color: rgb(0,128,0)"&gt;--returns 1

&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;Select&lt;/span&gt; dbo&lt;span style="color: rgb(128,128,128)"&gt;.&lt;/span&gt;RegExReplace&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt;'333-4444'&lt;/span&gt;&lt;span style="color: rgb(128,128,128)"&gt;,&lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt;'(\d+)-(\d+)'&lt;/span&gt;&lt;span style="color: rgb(128,128,128)"&gt;,&lt;/span&gt; &lt;span style="color: rgb(255,0,0)"&gt;'$2-$1'&lt;/span&gt;&lt;span style="color: rgb(128,128,128)"&gt;)
&lt;/span&gt;&lt;span style="color: rgb(0,128,0)"&gt;--reverses two numbers seperated by a dash returns 4444-333&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;And that's all needed. If you would like to check out the source code for creating the original dll and compiling it, have a look &lt;a title="Regular Expressions in SQL CLR" href="http://anastasiosyal.com/archive/2008/07/05/regular-expressions-in-ms-sql-server-using-clr.aspx"&gt;here&lt;/a&gt;&lt;/p&gt;&lt;img src="http://anastasiosyal.com/aggbug/15.aspx" width="1" height="1" /&gt;&lt;img src="http://feeds.feedburner.com/~r/anastasiosyal/~4/dXutJ5wihjE" height="1" width="1"/&gt;</description>
            <dc:creator>Anastasios Yalanopoulos</dc:creator>
            <guid>http://anastasiosyal.com/archive/2008/07/17/sql-clr-without-dll-dependency-for-your-production-server.aspx</guid>
            <pubDate>Thu, 17 Jul 2008 19:32:38 GMT</pubDate>
            <wfw:comment>http://anastasiosyal.com/comments/15.aspx</wfw:comment>
            <comments>http://anastasiosyal.com/archive/2008/07/17/sql-clr-without-dll-dependency-for-your-production-server.aspx#feedback</comments>
            <slash:comments>1</slash:comments>
            <wfw:commentRss>http://anastasiosyal.com/comments/commentRss/15.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Regular Expressions In MS SQL Server using CLR</title>
            <link>http://anastasiosyal.com/archive/2008/07/05/regular-expressions-in-ms-sql-server-using-clr.aspx</link>
            <description>&lt;p&gt;In this post I'll show just how easy it is to make your SQL Server 2005 database support Regular Expressions through what is known as SQL CLR&lt;/p&gt;  &lt;p&gt;Just Fire up Visual Studio and create a new library project (I called it TextFunctions)&lt;/p&gt;  &lt;p&gt;Add a new Class and Call it Regular Expressions and simply paste in the following Code: &lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: rgb(0,0,255)"&gt;using&lt;/span&gt; Microsoft.SqlServer.Server;
&lt;span style="color: rgb(0,0,255)"&gt;using&lt;/span&gt; System.Text.RegularExpressions;
&lt;span style="color: rgb(0,0,255)"&gt;using&lt;/span&gt; System.Data.SqlTypes;


    &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;class&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;RegularExpressions
&lt;/span&gt;    {
        [Microsoft.SqlServer.Server.&lt;span style="color: rgb(43,145,175)"&gt;SqlFunction&lt;/span&gt;(IsDeterministic=&lt;span style="color: rgb(0,0,255)"&gt;true&lt;/span&gt;, IsPrecise=&lt;span style="color: rgb(0,0,255)"&gt;true&lt;/span&gt;)]
        &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;static&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;SqlBoolean&lt;/span&gt; RegExMatch(&lt;span style="color: rgb(43,145,175)"&gt;SqlString&lt;/span&gt; input, &lt;span style="color: rgb(43,145,175)"&gt;SqlString&lt;/span&gt; pattern)
        {
            &lt;span style="color: rgb(0,0,255)"&gt;if&lt;/span&gt; (input.IsNull || pattern.IsNull) &lt;span style="color: rgb(0,128,0)"&gt;//nulls dont qualify for a match
&lt;/span&gt;                &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;SqlBoolean&lt;/span&gt;.False;
            
            &lt;span style="color: rgb(0,128,0)"&gt;//Use the static IsMatch method. This is more performant than creating a 
&lt;/span&gt;            &lt;span style="color: rgb(0,128,0)"&gt;// new instance of Regex as the static method also caches the last expressions we used. 
&lt;/span&gt;            &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;Regex&lt;/span&gt;.IsMatch(input.Value, pattern.Value, &lt;span style="color: rgb(43,145,175)"&gt;RegexOptions&lt;/span&gt;.IgnoreCase);
        }

        [Microsoft.SqlServer.Server.&lt;span style="color: rgb(43,145,175)"&gt;SqlFunction&lt;/span&gt;(IsDeterministic = &lt;span style="color: rgb(0,0,255)"&gt;true&lt;/span&gt;, IsPrecise = &lt;span style="color: rgb(0,0,255)"&gt;true&lt;/span&gt;)]
        &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;static&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;SqlString&lt;/span&gt; RegExReplace(&lt;span style="color: rgb(43,145,175)"&gt;SqlString&lt;/span&gt; input, &lt;span style="color: rgb(43,145,175)"&gt;SqlString&lt;/span&gt; pattern, &lt;span style="color: rgb(43,145,175)"&gt;SqlString&lt;/span&gt; replacement)
        {
            &lt;span style="color: rgb(0,0,255)"&gt;if&lt;/span&gt; (input.IsNull || pattern.IsNull || replacement.IsNull)
                &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;SqlString&lt;/span&gt;.Null;

            &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;SqlString&lt;/span&gt;(&lt;span style="color: rgb(43,145,175)"&gt;Regex&lt;/span&gt;.Replace(input.Value, pattern.Value, replacement.Value, &lt;span style="color: rgb(43,145,175)"&gt;RegexOptions&lt;/span&gt;.IgnoreCase));
        }
    }&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;In this example we have two functions: one to Match a Regular expression pattern and one to perform a Replace based on a regular expression pattern. &lt;/p&gt;

&lt;p&gt;To enable our SQL Server database to make use of the above functions we need to follow the steps below:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Compile the library for Release &lt;/li&gt;

  &lt;li&gt;CLR Enable Sql Server with: &lt;/li&gt;
&lt;/ul&gt;

&lt;pre class="code"&gt;&lt;span style="color: rgb(128,0,0)"&gt;sp_configure&lt;/span&gt; &lt;span style="color: rgb(255,0,0)"&gt;'clr enabled'&lt;/span&gt;&lt;span style="color: rgb(128,128,128)"&gt;,&lt;/span&gt; 1
&lt;span style="color: rgb(0,0,255)"&gt;RECONFIGURE&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;WITH&lt;/span&gt; OVERRIDE&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;Reference the assembly and register the functions:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: rgb(0,0,255)"&gt;CREATE&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;ASSEMBLY&lt;/span&gt; TextFunctions &lt;span style="color: rgb(0,0,255)"&gt;FROM&lt;/span&gt; &lt;span style="color: rgb(255,0,0)"&gt;'c:\Development\Testing\CLR\TextFunctions\bin\Release\TextFunctions.dll'
&lt;/span&gt;GO
&lt;span style="color: rgb(0,0,255)"&gt;CREATE&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Function&lt;/span&gt; RegExMatch&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;@Input &lt;span style="color: rgb(0,0,255)"&gt;NVARCHAR&lt;/span&gt;&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;512&lt;span style="color: rgb(128,128,128)"&gt;),&lt;/span&gt;@Pattern &lt;span style="color: rgb(0,0,255)"&gt;NVARCHAR&lt;/span&gt;&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;127&lt;span style="color: rgb(128,128,128)"&gt;))
&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;RETURNS&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;BIT
EXTERNAL&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;NAME&lt;/span&gt; TextFunctions&lt;span style="color: rgb(128,128,128)"&gt;.&lt;/span&gt;RegularExpressions&lt;span style="color: rgb(128,128,128)"&gt;.&lt;/span&gt;RegExMatch
GO
&lt;span style="color: rgb(0,0,255)"&gt;CREATE&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;Function&lt;/span&gt; RegExReplace&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;@Input &lt;span style="color: rgb(0,0,255)"&gt;NVARCHAR&lt;/span&gt;&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;512&lt;span style="color: rgb(128,128,128)"&gt;),&lt;/span&gt;@Pattern &lt;span style="color: rgb(0,0,255)"&gt;NVARCHAR&lt;/span&gt;&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;127&lt;span style="color: rgb(128,128,128)"&gt;),&lt;/span&gt; @Replacement &lt;span style="color: rgb(0,0,255)"&gt;NVARCHAR&lt;/span&gt;&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;512&lt;span style="color: rgb(128,128,128)"&gt;))
&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;RETURNS&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;NVARCHAR&lt;/span&gt;&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;512&lt;span style="color: rgb(128,128,128)"&gt;)
&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;EXTERNAL&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;NAME&lt;/span&gt; TextFunctions&lt;span style="color: rgb(128,128,128)"&gt;.&lt;/span&gt;RegularExpressions&lt;span style="color: rgb(128,128,128)"&gt;.&lt;/span&gt;RegExReplace
GO&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;Now we're ready to put our new functions to the test:&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: rgb(0,0,255)"&gt;select&lt;/span&gt; dbo&lt;span style="color: rgb(128,128,128)"&gt;.&lt;/span&gt;RegExMatch&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt;'me@mymail.com'&lt;/span&gt;&lt;span style="color: rgb(128,128,128)"&gt;,&lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt;'^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,6}$'&lt;/span&gt;&lt;span style="color: rgb(128,128,128)"&gt;)
&lt;/span&gt;&lt;span style="color: rgb(0,128,0)"&gt;--Verifies an email address

&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;SELECT&lt;/span&gt; dbo&lt;span style="color: rgb(128,128,128)"&gt;.&lt;/span&gt;RegExMatch&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt;'12354'&lt;/span&gt;&lt;span style="color: rgb(128,128,128)"&gt;,&lt;/span&gt; &lt;span style="color: rgb(255,0,0)"&gt;'\d'&lt;/span&gt;&lt;span style="color: rgb(128,128,128)"&gt;)
&lt;/span&gt;&lt;span style="color: rgb(0,128,0)"&gt;--Verifies number Returns 1

&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;SELECT&lt;/span&gt; dbo&lt;span style="color: rgb(128,128,128)"&gt;.&lt;/span&gt;RegExReplace&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt;'Poem Title (Author)'&lt;/span&gt;&lt;span style="color: rgb(128,128,128)"&gt;,&lt;/span&gt; &lt;span style="color: rgb(255,0,0)"&gt;'.*?\((.*?)\).*'&lt;/span&gt;&lt;span style="color: rgb(128,128,128)"&gt;,&lt;/span&gt; &lt;span style="color: rgb(255,0,0)"&gt;'$1'&lt;/span&gt;&lt;span style="color: rgb(128,128,128)"&gt;)
&lt;/span&gt;&lt;span style="color: rgb(0,128,0)"&gt;-- Returns the match within the parenthesis, returns: Author (Useful for splitting one column in two)

&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;SELECT&lt;/span&gt; EmailAddress&lt;span style="color: rgb(128,128,128)"&gt;,&lt;/span&gt; dbo&lt;span style="color: rgb(128,128,128)"&gt;.&lt;/span&gt;RegExMatch&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;EmailAddress&lt;span style="color: rgb(128,128,128)"&gt;,&lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt;'^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,6}$'&lt;/span&gt;&lt;span style="color: rgb(128,128,128)"&gt;)&lt;/span&gt; 
&lt;span style="color: rgb(0,0,255)"&gt;FROM&lt;/span&gt; Users 
&lt;span style="color: rgb(0,0,255)"&gt;ORDER&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;BY&lt;/span&gt; 2 
&lt;span style="color: rgb(0,128,0)"&gt;--Checks your users table for Invalid Email addresses, 
--at the top of the results all users with invalid email addresses&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;Regular expressions can come in really handy especially in data cleansing/transformation operations in your database. &lt;/p&gt;

&lt;p&gt;Here are some further pointers to boost creativity with regular expressions:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.regular-expressions.info/email.html"&gt;&lt;strong&gt;Email Validation with Regular Expressions&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt; 
    &lt;br /&gt;&lt;/strong&gt;&lt;a href="http://www.addedbytes.com/cheat-sheets/regular-expressions-cheat-sheet"&gt;&lt;strong&gt;Regular Expressions Cheat Sheet&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt; 
    &lt;br /&gt;&lt;/strong&gt;&lt;a href="http://www.regexlib.com"&gt;&lt;strong&gt;RegExLib - Library of Regular Expressions for .Net&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://anastasiosyal.com/aggbug/14.aspx" width="1" height="1" /&gt;&lt;img src="http://feeds.feedburner.com/~r/anastasiosyal/~4/My51NzD9dCc" height="1" width="1"/&gt;</description>
            <dc:creator>Anastasios Yalanopoulos</dc:creator>
            <guid>http://anastasiosyal.com/archive/2008/07/05/regular-expressions-in-ms-sql-server-using-clr.aspx</guid>
            <pubDate>Sat, 05 Jul 2008 14:31:39 GMT</pubDate>
            <wfw:comment>http://anastasiosyal.com/comments/14.aspx</wfw:comment>
            <comments>http://anastasiosyal.com/archive/2008/07/05/regular-expressions-in-ms-sql-server-using-clr.aspx#feedback</comments>
            <slash:comments>6</slash:comments>
            <wfw:commentRss>http://anastasiosyal.com/comments/commentRss/14.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Disable Text Wrapping in Excel Export of Reporting Services</title>
            <link>http://anastasiosyal.com/archive/2008/07/01/Disable-Text-Wrapping-in-Excel-Export-of-Reporting-Services.aspx</link>
            <description>&lt;p&gt;Well, i guess that's a pretty elaborate title, but it's what this post is about. How you text-wrapping when exporting to Excel via SQL Server Reporting services 2005 on the web be disabled. &lt;/p&gt;  &lt;p&gt;It is unfortunate that there is no configuration option in when authoring a report to control whether the text can wrap or not. &lt;/p&gt;  &lt;h3&gt;Why disable text wrapping?&lt;/h3&gt;  &lt;p&gt;&lt;a href="http://anastasiosyal.com/images/anastasiosyal_com/WindowsLiveWriter/DisableTextWrappinginExcelExportofReport_745/image_2.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="91" alt="image" src="http://anastasiosyal.com/images/anastasiosyal_com/WindowsLiveWriter/DisableTextWrappinginExcelExportofReport_745/image_thumb.png" width="382" border="0" /&gt;&lt;/a&gt;  &lt;br /&gt;    &lt;br /&gt;In the above screenshot we can see that when a given cell is constrained in size (i.e fixed height).     &lt;br /&gt;&lt;em&gt;With text wrap on&lt;/em&gt;: the cell will not show the complete text unless it is wide enough.     &lt;br /&gt;&lt;em&gt;With text wrap off&lt;/em&gt;: the complete text will display by overflowing onto the adjacent empty cells. So long as the next cells are empty.&lt;/p&gt;  &lt;p&gt;But why would I want to do that when I could simply merge cells B + C + D together? It all comes down to usability and user expectations. If the end user expects to be able to sort the data in the columns then merged cells is just a feature that will be an obstacle in his path. In the screenshot below I try to sort by column B, but 1 of the rows contains merged cells so Excel naturally prompts the user. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://anastasiosyal.com/images/anastasiosyal_com/WindowsLiveWriter/DisableTextWrappinginExcelExportofReport_745/image_6.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="182" alt="image" src="http://anastasiosyal.com/images/anastasiosyal_com/WindowsLiveWriter/DisableTextWrappinginExcelExportofReport_745/image_thumb_2.png" width="298" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;   &lt;br /&gt;If you do find yourself with a reporting services report that you have spent hours creating in your report designer and you are handed the above niche requirement, there are the following options for you friend: &lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Fix it manually through automation &lt;/li&gt;    &lt;li&gt;Buy a third party product that has more control over the export such as &lt;a title="http://officewriter.softartisans.com/OfficeWriter-250.aspx" href="http://officewriter.softartisans.com/OfficeWriter-250.aspx"&gt;http://officewriter.softartisans.com/OfficeWriter-250.aspx&lt;/a&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;If a third party product is not an option for you, you may find the following helpful.&lt;/p&gt;  &lt;h3&gt;Disable Text Wrap using Microsoft.Office.Interop.Excel&lt;/h3&gt;  &lt;p&gt;Office.Interop requires that Excel is installed on the machine that will render the report. Here is the function required:    &lt;br /&gt;&lt;/p&gt;  &lt;pre class="code"&gt;        &lt;span style="color: rgb(0,0,255)"&gt;private&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;static&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;void&lt;/span&gt; DisableTextWrap(&lt;span style="color: rgb(0,0,255)"&gt;string&lt;/span&gt; fileName)
        {

            &lt;span style="color: rgb(43,145,175)"&gt;Application&lt;/span&gt; excel = &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;Application&lt;/span&gt;();
            &lt;span style="color: rgb(0,0,255)"&gt;try
&lt;/span&gt;            {
                &lt;span style="color: rgb(43,145,175)"&gt;Workbook&lt;/span&gt; workbook = excel.Workbooks.Open(
                        fileName,
                        &lt;span style="color: rgb(43,145,175)"&gt;Type&lt;/span&gt;.Missing, &lt;span style="color: rgb(0,0,255)"&gt;false&lt;/span&gt;, &lt;span style="color: rgb(43,145,175)"&gt;Type&lt;/span&gt;.Missing, &lt;span style="color: rgb(43,145,175)"&gt;Type&lt;/span&gt;.Missing,
                        &lt;span style="color: rgb(43,145,175)"&gt;Type&lt;/span&gt;.Missing, &lt;span style="color: rgb(0,0,255)"&gt;true&lt;/span&gt;, &lt;span style="color: rgb(43,145,175)"&gt;Type&lt;/span&gt;.Missing, &lt;span style="color: rgb(43,145,175)"&gt;Type&lt;/span&gt;.Missing,
                        &lt;span style="color: rgb(43,145,175)"&gt;Type&lt;/span&gt;.Missing, &lt;span style="color: rgb(43,145,175)"&gt;Type&lt;/span&gt;.Missing, &lt;span style="color: rgb(43,145,175)"&gt;Type&lt;/span&gt;.Missing, &lt;span style="color: rgb(43,145,175)"&gt;Type&lt;/span&gt;.Missing,
                        &lt;span style="color: rgb(43,145,175)"&gt;Type&lt;/span&gt;.Missing, &lt;span style="color: rgb(43,145,175)"&gt;Type&lt;/span&gt;.Missing);
                &lt;span style="color: rgb(0,0,255)"&gt;try
&lt;/span&gt;                {
                    &lt;span style="color: rgb(43,145,175)"&gt;Worksheet&lt;/span&gt; wsheet = workbook.Sheets[1] &lt;span style="color: rgb(0,0,255)"&gt;as&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;Worksheet&lt;/span&gt;;
                    &lt;span style="color: rgb(0,0,255)"&gt;try
&lt;/span&gt;                    {
                        &lt;span style="color: rgb(43,145,175)"&gt;Range&lt;/span&gt; excelRange = wsheet.UsedRange;
                        &lt;span style="color: rgb(0,0,255)"&gt;try
&lt;/span&gt;                        {
                            excelRange.WrapText = &lt;span style="color: rgb(0,0,255)"&gt;false&lt;/span&gt;;
                        }
                        &lt;span style="color: rgb(0,0,255)"&gt;finally
&lt;/span&gt;                        {
                            &lt;span style="color: rgb(43,145,175)"&gt;Marshal&lt;/span&gt;.ReleaseComObject(excelRange);
                        }
                    }
                    &lt;span style="color: rgb(0,0,255)"&gt;finally
&lt;/span&gt;                    {
                        &lt;span style="color: rgb(43,145,175)"&gt;Marshal&lt;/span&gt;.ReleaseComObject(wsheet);
                    }
                    workbook.Save();

                }
                &lt;span style="color: rgb(0,0,255)"&gt;finally
&lt;/span&gt;                {
                    workbook.Close(&lt;span style="color: rgb(0,0,255)"&gt;false&lt;/span&gt;, fileName, &lt;span style="color: rgb(0,0,255)"&gt;null&lt;/span&gt;);
                    &lt;span style="color: rgb(43,145,175)"&gt;Marshal&lt;/span&gt;.ReleaseComObject(workbook);
                }
            }
            &lt;span style="color: rgb(0,0,255)"&gt;finally
&lt;/span&gt;            {
                excel.Quit();
                &lt;span style="color: rgb(43,145,175)"&gt;Marshal&lt;/span&gt;.ReleaseComObject(excel);
            }
        }&lt;/pre&gt;

&lt;p&gt;The above function will open an excel file and disable text-wrap in the used area of only the first spreadsheet&lt;/p&gt;

&lt;h3&gt;Enable a Web Server to run Excel through COM automation&lt;/h3&gt;

&lt;p&gt;In order to enable a web server to run Excel through COM automation you can follow this very helpful and detailed advice: &lt;/p&gt;

&lt;p&gt;&lt;a title="http://blog.crowe.co.nz/archive/2006/03/02/589.aspx" href="http://blog.crowe.co.nz/archive/2006/03/02/589.aspx"&gt;http://blog.crowe.co.nz/archive/2006/03/02/589.aspx&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;One point to note after following the above instructions
  &lt;br /&gt;After running DCOMCNFG

  &lt;br /&gt;In the Security Tab

  &lt;br /&gt;Under Activation  &lt;br /&gt;Click customise. I would recommend that the excel is launched (activated) by a user that has already used excel once on the server you are trying to perform this. So, first create a user, then go to Excel right click and use 'Run As..' option and select the newly created user. The reason for doing this is that when a user runs excel for the first time, excel creates a profile for them and does some custom installation and also pops up a dialog box which is something we would like to avoid during the COM automation. Doing this will ensure that the installation of the user profile is not trying to take place under the COM automation.  &lt;br /&gt;&lt;/p&gt;

&lt;p&gt;Hope this helps someone! &lt;/p&gt;&lt;img src="http://anastasiosyal.com/aggbug/13.aspx" width="1" height="1" /&gt;&lt;img src="http://feeds.feedburner.com/~r/anastasiosyal/~4/h8_J0wTdt0M" height="1" width="1"/&gt;</description>
            <dc:creator>Anastasios Yalanopoulos</dc:creator>
            <guid>http://anastasiosyal.com/archive/2008/07/01/Disable-Text-Wrapping-in-Excel-Export-of-Reporting-Services.aspx</guid>
            <pubDate>Tue, 01 Jul 2008 19:44:36 GMT</pubDate>
            <wfw:comment>http://anastasiosyal.com/comments/13.aspx</wfw:comment>
            <comments>http://anastasiosyal.com/archive/2008/07/01/Disable-Text-Wrapping-in-Excel-Export-of-Reporting-Services.aspx#feedback</comments>
            <slash:comments>2</slash:comments>
            <wfw:commentRss>http://anastasiosyal.com/comments/commentRss/13.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Quick Tip: Use Hashbytes to create a Hash in TSQL in SQL Server</title>
            <link>http://anastasiosyal.com/archive/2008/04/23/quick-tip-use-hashbytes-to-create-a-hash-in-tsql.aspx</link>
            <description>Just a quick tip.   &lt;br /&gt;I was unaware until recently that SQL Server 2005 has nicely built in support for hashing and it is called &lt;b&gt;hashbytes&lt;/b&gt;   &lt;br /&gt;  &lt;br /&gt;HashBytes ( '&amp;lt;algorithm&amp;gt;', { @input | 'input' } )   &lt;br /&gt;&amp;lt;algorithm&amp;gt;::= MD2 | MD4 | MD5 | SHA | SHA1   &lt;p&gt;Parameters are the algorithm you wish to hash to and the input string to hash.    &lt;br /&gt;Here is a sample along with the return values commented in the next line:     &lt;br /&gt;&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: rgb(0,0,255)"&gt;Select&lt;/span&gt; HashBytes&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt;'MD2'&lt;/span&gt;&lt;span style="color: rgb(128,128,128)"&gt;,&lt;/span&gt; &lt;span style="color: rgb(255,0,0)"&gt;'Hello world!'&lt;/span&gt;&lt;span style="color: rgb(128,128,128)"&gt;)&lt;/span&gt; 
&lt;span style="color: rgb(0,128,0)"&gt;--0x63503D3117AD33F941D20F57144ECE64

&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;Select&lt;/span&gt; HashBytes&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt;'MD4'&lt;/span&gt;&lt;span style="color: rgb(128,128,128)"&gt;,&lt;/span&gt; &lt;span style="color: rgb(255,0,0)"&gt;'Hello world!'&lt;/span&gt;&lt;span style="color: rgb(128,128,128)"&gt;)&lt;/span&gt; 
&lt;span style="color: rgb(0,128,0)"&gt;--0x0D7A9DB5A3BED4AE5738EE6D1909649C

&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;Select&lt;/span&gt; HashBytes&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt;'MD5'&lt;/span&gt;&lt;span style="color: rgb(128,128,128)"&gt;,&lt;/span&gt; &lt;span style="color: rgb(255,0,0)"&gt;'Hello world!'&lt;/span&gt;&lt;span style="color: rgb(128,128,128)"&gt;)&lt;/span&gt; 
&lt;span style="color: rgb(0,128,0)"&gt;--0x86FB269D190D2C85F6E0468CECA42A20

&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;Select&lt;/span&gt; HashBytes&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt;'SHA'&lt;/span&gt;&lt;span style="color: rgb(128,128,128)"&gt;,&lt;/span&gt; &lt;span style="color: rgb(255,0,0)"&gt;'Hello world!'&lt;/span&gt;&lt;span style="color: rgb(128,128,128)"&gt;)&lt;/span&gt; 
&lt;span style="color: rgb(0,128,0)"&gt;--0xD3486AE9136E7856BC42212385EA797094475802

&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;Select&lt;/span&gt; HashBytes&lt;span style="color: rgb(128,128,128)"&gt;(&lt;/span&gt;&lt;span style="color: rgb(255,0,0)"&gt;'SHA1'&lt;/span&gt;&lt;span style="color: rgb(128,128,128)"&gt;,&lt;/span&gt; &lt;span style="color: rgb(255,0,0)"&gt;'Hello world!'&lt;/span&gt;&lt;span style="color: rgb(128,128,128)"&gt;)&lt;/span&gt; 
&lt;span style="color: rgb(0,128,0)"&gt;--0xD3486AE9136E7856BC42212385EA797094475802&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;
    &lt;br /&gt;MSDN: &lt;/strong&gt;&lt;a title="http://msdn2.microsoft.com/en-us/library/ms174415.aspx" href="http://msdn2.microsoft.com/en-us/library/ms174415.aspx"&gt;http://msdn2.microsoft.com/en-us/library/ms174415.aspx&lt;/a&gt;&lt;/p&gt;&lt;img src="http://anastasiosyal.com/aggbug/12.aspx" width="1" height="1" /&gt;&lt;img src="http://feeds.feedburner.com/~r/anastasiosyal/~4/JNby-_XzrcU" height="1" width="1"/&gt;</description>
            <dc:creator>Anastasios Yalanopoulos</dc:creator>
            <guid>http://anastasiosyal.com/archive/2008/04/23/quick-tip-use-hashbytes-to-create-a-hash-in-tsql.aspx</guid>
            <pubDate>Wed, 23 Apr 2008 19:03:00 GMT</pubDate>
            <wfw:comment>http://anastasiosyal.com/comments/12.aspx</wfw:comment>
            <comments>http://anastasiosyal.com/archive/2008/04/23/quick-tip-use-hashbytes-to-create-a-hash-in-tsql.aspx#feedback</comments>
            <slash:comments>9</slash:comments>
            <wfw:commentRss>http://anastasiosyal.com/comments/commentRss/12.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Expose your objects over HTTP with minimal coding</title>
            <link>http://anastasiosyal.com/archive/2008/03/24/expose-your-objects-over-http-with-minimal-coding.aspx</link>
            <description>&lt;p&gt;Quite often we create systems that make use of web services so as to expose our Data, or Business methods for client applications to consume them. In a classic 3 tier scenario it may be either the data layer exposed through the web service as a data service, or the business layer exposed through the web service as a business service. I would say that both are perfectly valid for exposure through a web service depending on our needs and requirements. But since web services already exist, why make a custom method and use this method instead of web services? The following paragraph contains some points I dont like when coding standard microsoft web services. &lt;/p&gt;  &lt;h3&gt; &lt;/h3&gt;  &lt;h3&gt;Points I don't like when using Microsoft Web Services. &lt;/h3&gt;  &lt;p&gt;What I do not like when coding a web service when using the standard .Net framework approach is the feeling of &lt;strong&gt;redundant coding &lt;/strong&gt;I get. Surely you've felt the same at some point, especially when all we are doing is simply &lt;strong&gt;coding pass through functions &lt;/strong&gt;to my business or data layer. &lt;/p&gt;  &lt;p&gt;Further to that, I end up having to &lt;strong&gt;maintain&lt;/strong&gt; a mess of &lt;strong&gt;web service references&lt;/strong&gt; in my client application. I need to add one reference to each asmx page created. Further to this, when creating web service references, the Microsoft .Net framework will create a custom Proxy to access this web service. This custom proxy will also re-define any complex types (eg typed datasets or custom classes) returned through the web service. What i dont like about this, is that even though two seperate asmx files may expose the same type, each web service reference added will &lt;strong&gt;redifine the same type &lt;/strong&gt;on its own copy of the proxy. This leaves the client application with multiple definitions of what essentially is the same data type. &lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;h3&gt;&lt;/h3&gt;  &lt;h3&gt; &lt;a href="http://anastasiosyal.com/images/anastasiosyal_com/WindowsLiveWriter/72c3bdee8480_1200A/image_4.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; margin: 0px 25px 0px 0px; border-right-width: 0px" height="339" alt="image" src="http://anastasiosyal.com/images/anastasiosyal_com/WindowsLiveWriter/72c3bdee8480_1200A/image_thumb_1.png" width="184" align="left" border="0" /&gt;&lt;/a&gt; What would I like to see instead?&lt;/h3&gt;  &lt;ul&gt;   &lt;li&gt;I would like to be able to switch between 'web service' mode and 'non web service' mode easily, with just a simple switch in the client application.      &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;I do not want to create redundant code in webmethods just so that I can expose my data or business objects over HTTP. The code is already in those layers, I just want the ability to consume them over an HTTP connection.      &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;i would just like to add a 'magic' attribute to my business/data classes that would mean 'This object can be invoked over HTTP.      &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;I would like to be able to consume my business or data objects seamlessly, with no requirements to add tons of web references on my client application. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;For these reasons, i thought it would be worthwhile to find a method of dynamically exposing my data or business objects over an HTTP channel. I'd like to share a solution which addresses the above issues, but as in most cases there are tradeoffs.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Whats the tradeoff though? &lt;/strong&gt;The tradeoff is that &lt;strong&gt;this is not webservices &lt;/strong&gt;and because of that, this custom HTTP invocation protocol is &lt;strong&gt;not interoperable &lt;/strong&gt;across other non .Net platforms. &lt;/p&gt;  &lt;p&gt;If interoperability is a requirement in your application then this post does not offer any solutions to the above points. If however interoperability with other platforms is not a requirement, then you may find this helpful. Furthermore this solution requires that your Base Business or Data objects inherit from ContextBoundObject, but this requirement could be overcome in a different implementation. &lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;h3&gt;&lt;/h3&gt;  &lt;h3&gt;&lt;/h3&gt;  &lt;h3&gt;Method Interception and how this solution works. &lt;/h3&gt;  &lt;p&gt;This solution is based on the following bullet points:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Create an object and &lt;strong&gt;intercept all method calls&lt;/strong&gt; to that object &lt;/li&gt;    &lt;li&gt;Determine if we are in a 'web service mode' &lt;/li&gt;    &lt;li&gt;if we are not in 'web service mode', then just call the underlying dataobject method and return its value. &lt;/li&gt;    &lt;li&gt;If we are in 'web service mode' then marshal the call accross to a custom HTTP Handler, this handler will create the dataobject via reflection execute the method and return the value (if any) and output parameters. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;The key point of this architecture is the ability to intercept method calls to the object, as soon as we intercept method calls we can decide whether we route the request to the underlying object, or route the request over HTTP to our Handler. This handler is generic and does not require any code modifications. It does however require a reference to our dll that contains our DAL classes. &lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;Thomas Danecker has an excellent post about how to intercept methods with a custom proxy.    &lt;br /&gt;&lt;a title="http://tdanecker.blogspot.com/2007/09/interception-with-proxies.html" href="http://tdanecker.blogspot.com/2007/09/interception-with-proxies.html"&gt;http://tdanecker.blogspot.com/2007/09/interception-with-proxies.html&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;I like that solution because it uses only classes from the .Net framework. What I dont like about it, is the requirement it emposes on the proxyable types to derive from the ContextBoundObject type.&lt;/p&gt;  &lt;p&gt;Oren has a nice short post where he compares 7 different options when it comes to method interception, with pros and cons of each:    &lt;br /&gt;&lt;a title="http://www.ayende.com/Blog/archive/2007/07/02/7-Approaches-for-AOP-in-.Net.aspx" href="http://www.ayende.com/Blog/archive/2007/07/02/7-Approaches-for-AOP-in-.Net.aspx"&gt;http://www.ayende.com/Blog/archive/2007/07/02/7-Approaches-for-AOP-in-.Net.aspx&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;   &lt;br /&gt;This solution uses interception with native Microsoft .Net classes as per Thomas's example. &lt;/p&gt;  &lt;h3&gt;&lt;/h3&gt;  &lt;h3&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/h3&gt;  &lt;h3&gt;   &lt;br /&gt;Ok, now some code!&lt;/h3&gt;  &lt;p&gt;&lt;a href="http://anastasiosyal.com/images/anastasiosyal_com/WindowsLiveWriter/72c3bdee8480_1200A/image_6.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; margin: 0px; border-right-width: 0px" height="656" alt="image" src="http://anastasiosyal.com/images/anastasiosyal_com/WindowsLiveWriter/72c3bdee8480_1200A/image_thumb_2.png" width="232" align="right" border="0" /&gt;&lt;/a&gt; Our sample application consists of a DAL, a BLL a UI and a Test Project with some Test Cases. Our project also includes the Dynamic Service itself. So, let's see some of this in action and how it would all fit together. For the purpose of this test, our UI is a console application. This is what it would typically look like. &lt;/p&gt;  &lt;p&gt;Listing #1: &lt;/p&gt;  &lt;pre class="code" style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; overflow: hidden; border-right-width: 0px"&gt;&lt;span style="color: rgb(0,0,255)"&gt;using&lt;/span&gt; System;
&lt;span style="color: rgb(0,0,255)"&gt;using&lt;/span&gt; System.Text;
&lt;span style="color: rgb(0,0,255)"&gt;using&lt;/span&gt; DynamicService.Library;
&lt;span style="color: rgb(0,0,255)"&gt;using&lt;/span&gt; DynamicService.DAL;

&lt;span style="color: rgb(0,0,255)"&gt;namespace&lt;/span&gt; DynamicService.UI
{
    &lt;span style="color: rgb(0,0,255)"&gt;class&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;Program
&lt;/span&gt;    {
        &lt;span style="color: rgb(0,0,255)"&gt;static&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;void&lt;/span&gt; Main(&lt;span style="color: rgb(0,0,255)"&gt;string&lt;/span&gt;[] args)
        {

            &lt;span style="color: rgb(0,0,255)"&gt;using&lt;/span&gt; (&lt;span style="color: rgb(43,145,175)"&gt;WebServiceSettingsScope&lt;/span&gt; settingScope = 
                    &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;WebServiceSettingsScope&lt;/span&gt;(&lt;br /&gt;&lt;span style="color: rgb(163,21,21)"&gt;"http://localhost:4040/Dataservice.ashx?db=TestDb"&lt;/span&gt;, &lt;span style="color: rgb(163,21,21)"&gt;""&lt;/span&gt;, &lt;span style="color: rgb(163,21,21)"&gt;""&lt;/span&gt;, 3000))
            {
                &lt;span style="color: rgb(43,145,175)"&gt;TestDal&lt;/span&gt; dal = &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;TestDal&lt;/span&gt;();
                &lt;span style="color: rgb(0,0,255)"&gt;int&lt;/span&gt; i = dal.ReturnInputParameter(10);

                &lt;span style="color: rgb(43,145,175)"&gt;Console&lt;/span&gt;.WriteLine(i);
            }

            &lt;span style="color: rgb(43,145,175)"&gt;Console&lt;/span&gt;.ReadKey();
        }
    }
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;br /&gt;

&lt;br /&gt;

&lt;p&gt;And this is what our TestDal class would look like (listing #2):&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: rgb(0,0,255)"&gt;using&lt;/span&gt; System;
&lt;span style="color: rgb(0,0,255)"&gt;using&lt;/span&gt; System.Text;
&lt;span style="color: rgb(0,0,255)"&gt;using&lt;/span&gt; System.Data;&lt;br /&gt;&lt;span style="color: rgb(0,0,255)"&gt;using&lt;/span&gt; DynamicService.Library;

&lt;span style="color: rgb(0,0,255)"&gt;namespace&lt;/span&gt; DynamicService.DAL
{
    [&lt;span style="color: rgb(43,145,175)"&gt;HttpRemotable&lt;/span&gt;]
    &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;class&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;TestDal&lt;/span&gt; : &lt;span style="color: rgb(43,145,175)"&gt;ContextBoundObject
&lt;/span&gt;    {

        &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; TestDal()
        {
            &lt;span style="color: rgb(0,128,0)"&gt;//This is how the dal knows it's connection string for example...
&lt;/span&gt;            &lt;span style="color: rgb(0,128,0)"&gt;//the code below could be added in a base dal class that would allow the derived data objects 
&lt;/span&gt;            &lt;span style="color: rgb(0,128,0)"&gt;//to know about the database they are talking to. (useful for multi database scenarios)
&lt;/span&gt;            &lt;span style="color: rgb(43,145,175)"&gt;DbConnectionStringSettings&lt;/span&gt; connectionStringSettings = 
                &lt;span style="color: rgb(43,145,175)"&gt;ConnectionSettingsScope&lt;/span&gt;.ActiveConnectionSettings &lt;span style="color: rgb(0,0,255)"&gt;as&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;DbConnectionStringSettings&lt;/span&gt;;
            &lt;span style="color: rgb(0,0,255)"&gt;string&lt;/span&gt; connectionString;
            &lt;span style="color: rgb(0,0,255)"&gt;if&lt;/span&gt; (connectionStringSettings != &lt;span style="color: rgb(0,0,255)"&gt;null&lt;/span&gt;)
                connectionString = connectionStringSettings.ConnectionString;
        }

        &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;int&lt;/span&gt; ReturnInputParameter(&lt;span style="color: rgb(0,0,255)"&gt;int&lt;/span&gt; param)
        {
            &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; param;
        }
    }
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;Well, this should get us going! So, the solution proposes that objects that can be invoked remotely over HTTP are decorated with an HttpRemotable attribute. They must also derive from ContextBoundObject so that their methods can be intercepted by the appropriate proxy and routed accordingly, either to the object directly, or to our generic handler. &lt;/p&gt;

&lt;p&gt;Listing #1 shows that the remotable object, in this case our TestDal, should be instantiated within a ConnectionSettingsScope. There are two types of connectionSettingsScope, two classes that derive from this class. There is a DbConnectionSettingsScope and a WebServiceSettingsScope. &lt;/p&gt;

&lt;p&gt;Depending on the scope that the TestDal object is being created it will be wrapped with either a ServiceProxy or an InterceptorProxy. The serviceproxy will route the requests to the service defined in the WebServiceSettingsScope. If created within a DbConnectionSettingsScope the InterceptorProxy will simply forward the requests on to the underlying object within the same application domain. &lt;/p&gt;

&lt;p&gt;How does this work behind the scenes? The decision of which Proxy is created is made within the HttpRemotableAttribute. &lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: rgb(0,0,255)"&gt;using&lt;/span&gt; System;
&lt;span style="color: rgb(0,0,255)"&gt;using&lt;/span&gt; System.Text;
&lt;span style="color: rgb(0,0,255)"&gt;using&lt;/span&gt; System.Runtime.Remoting.Proxies;

&lt;span style="color: rgb(0,0,255)"&gt;namespace&lt;/span&gt; DynamicService.Library
{
    &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;class&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;HttpRemotableAttribute&lt;/span&gt; : &lt;span style="color: rgb(43,145,175)"&gt;ProxyAttribute
&lt;/span&gt;    {
        &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;override&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;MarshalByRefObject&lt;/span&gt; CreateInstance(&lt;span style="color: rgb(43,145,175)"&gt;Type&lt;/span&gt; serverType)
        {
            &lt;span style="color: rgb(0,0,255)"&gt;if&lt;/span&gt; (!&lt;span style="color: rgb(43,145,175)"&gt;ConnectionSettingsScope&lt;/span&gt;.Exists)
                &lt;span style="color: rgb(0,0,255)"&gt;throw&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;Exception&lt;/span&gt;(&lt;span style="color: rgb(163,21,21)"&gt;"Error creating serviced object: "&lt;/span&gt;  + serverType.FullName + &lt;span style="color: rgb(163,21,21)"&gt;"\r\n\r\n You must define the ServiceScope to create a ServicedObject\r\ne.g. using(ServiceScope svcScope = new svcScope(...)) \r\n{ //object instantiation } \r\n\r\n"&lt;/span&gt;);

            &lt;span style="color: rgb(43,145,175)"&gt;RealProxy&lt;/span&gt; proxy = &lt;span style="color: rgb(0,0,255)"&gt;null&lt;/span&gt;;

            &lt;span style="color: rgb(0,128,0)"&gt;//if we are using a remote invocation then create a service proxy 
&lt;/span&gt;            &lt;span style="color: rgb(0,0,255)"&gt;if&lt;/span&gt; (&lt;span style="color: rgb(43,145,175)"&gt;ConnectionSettingsScope&lt;/span&gt;.UseRemoteInvocation)
            {
                &lt;span style="color: rgb(43,145,175)"&gt;WebServiceSettings&lt;/span&gt; webServiceSettings = &lt;span style="color: rgb(43,145,175)"&gt;ConnectionSettingsScope&lt;/span&gt;.ActiveConnectionSettings &lt;span style="color: rgb(0,0,255)"&gt;as&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;WebServiceSettings&lt;/span&gt;;
                &lt;span style="color: rgb(0,0,255)"&gt;if&lt;/span&gt; (webServiceSettings == &lt;span style="color: rgb(0,0,255)"&gt;null&lt;/span&gt;)
                    &lt;span style="color: rgb(0,0,255)"&gt;throw&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;Exception&lt;/span&gt;(&lt;span style="color: rgb(163,21,21)"&gt;"Unexpected error: the ConnectionScope.ActiveConnectionSettings is null."&lt;/span&gt;);

                proxy = &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;ServiceProxy&lt;/span&gt;(serverType, webServiceSettings);
            }
            &lt;span style="color: rgb(0,0,255)"&gt;else
&lt;/span&gt;            {
                &lt;span style="color: rgb(0,128,0)"&gt;//just create a dumb proxy that will forward on the requests locally
&lt;/span&gt;                proxy = &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;InterceptorProxy&lt;/span&gt;(serverType);
            }

            &lt;span style="color: rgb(43,145,175)"&gt;MarshalByRefObject&lt;/span&gt; transparentProxy = (&lt;span style="color: rgb(43,145,175)"&gt;MarshalByRefObject&lt;/span&gt;)proxy.GetTransparentProxy();
            &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; transparentProxy;
        }
    }
}&lt;/pre&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;HttpRemotable is a special attribute, inheriting from ProxyAttribute. What makes it so special is the CreateInstance method which is called when we try to create an instance of an object that is derived from ContextBoundObject and that is decorated with a ProxyAttribute derived class such as HttpRemotable. It determines the type of proxy to be created depending on the Active ConnectionSettings on our ConnectionSettings stack. &lt;/p&gt;

&lt;p&gt;What is this ConnectionSettingsScope that I keep refereing to? &lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: rgb(0,0,255)"&gt;using&lt;/span&gt; System;
&lt;span style="color: rgb(0,0,255)"&gt;using&lt;/span&gt; System.Text;
&lt;span style="color: rgb(0,0,255)"&gt;using&lt;/span&gt; System.Threading;
&lt;span style="color: rgb(0,0,255)"&gt;using&lt;/span&gt; System.Collections.Generic; &lt;br /&gt;&lt;span style="color: rgb(0,0,255)"&gt;using&lt;/span&gt; DynamicService.Library;

&lt;span style="color: rgb(0,0,255)"&gt;namespace&lt;/span&gt; DynamicService.Library
{

    &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;class&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;ConnectionSettingsScope&lt;/span&gt; : &lt;span style="color: rgb(43,145,175)"&gt;IDisposable
&lt;/span&gt;    {

        [&lt;span style="color: rgb(43,145,175)"&gt;ThreadStatic&lt;/span&gt;] &lt;span style="color: rgb(0,128,0)"&gt;//Each thread will have its own copy of a ServiceScope stack
&lt;/span&gt;        &lt;span style="color: rgb(0,0,255)"&gt;private&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;static&lt;/span&gt; Stack&amp;lt;&lt;span style="color: rgb(43,145,175)"&gt;ConnectionSettings&lt;/span&gt;&amp;gt; _ConnectionSettings;

        &lt;span style="color: rgb(0,0,255)"&gt;protected&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;static&lt;/span&gt; Stack&amp;lt;&lt;span style="color: rgb(43,145,175)"&gt;ConnectionSettings&lt;/span&gt;&amp;gt; ConnectionSettingsStack
        {
            &lt;span style="color: rgb(0,0,255)"&gt;get&lt;/span&gt; 
            {
                &lt;span style="color: rgb(0,128,0)"&gt;//this is thread safe, ConnectionSettings is a ThreadStatic variable.
&lt;/span&gt;                &lt;span style="color: rgb(0,0,255)"&gt;if&lt;/span&gt; (_ConnectionSettings == &lt;span style="color: rgb(0,0,255)"&gt;null&lt;/span&gt;)
                    _ConnectionSettings = &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; Stack&amp;lt;&lt;span style="color: rgb(43,145,175)"&gt;ConnectionSettings&lt;/span&gt;&amp;gt;();

                &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; _ConnectionSettings;
            }
        }

        &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; ConnectionSettingsScope(&lt;span style="color: rgb(43,145,175)"&gt;ConnectionSettings&lt;/span&gt; ConnectionSettings)
        {
            ConnectionSettingsStack.Push(ConnectionSettings);
        }

        &lt;span style="color: rgb(0,0,255)"&gt;static&lt;/span&gt; ConnectionSettingsScope()
        {

        }

        &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; ConnectionSettingsScope()
        {

        }


        &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;static&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;bool&lt;/span&gt; UseRemoteInvocation
        {
            &lt;span style="color: rgb(0,0,255)"&gt;get&lt;/span&gt; { &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; ActiveConnectionSettings &lt;span style="color: rgb(0,0,255)"&gt;is&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;WebServiceSettings&lt;/span&gt;; }
        }
        


        &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;static&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;bool&lt;/span&gt; Exists
        {
            &lt;span style="color: rgb(0,0,255)"&gt;get&lt;/span&gt; { &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; (ConnectionSettingsStack!= &lt;span style="color: rgb(0,0,255)"&gt;null&lt;/span&gt;) &amp;amp;&amp;amp; (ConnectionSettingsStack.Count &amp;gt; 0); }
        }

        &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;static&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;ConnectionSettings&lt;/span&gt; ActiveConnectionSettings
        {
            &lt;span style="color: rgb(0,0,255)"&gt;get&lt;/span&gt; { &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; GetCurrentThreadConnectionSettings(); }
        }

        &lt;span style="color: rgb(0,0,255)"&gt;private&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;static&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;ConnectionSettings&lt;/span&gt; GetCurrentThreadConnectionSettings()
        {
            &lt;span style="color: rgb(0,0,255)"&gt;if&lt;/span&gt; (ConnectionSettingsStack.Count &amp;gt; 0) 
                &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; ConnectionSettingsStack.Peek();
            &lt;span style="color: rgb(0,0,255)"&gt;else
&lt;/span&gt;                &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;null&lt;/span&gt;;
        }

        &lt;span style="color: rgb(0,128,0)"&gt;// Dispose() calls Dispose(true)
&lt;/span&gt;        &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;void&lt;/span&gt; Dispose()
        {
            Dispose(&lt;span style="color: rgb(0,0,255)"&gt;true&lt;/span&gt;);
            &lt;span style="color: rgb(43,145,175)"&gt;GC&lt;/span&gt;.SuppressFinalize(&lt;span style="color: rgb(0,0,255)"&gt;this&lt;/span&gt;);
        }

        &lt;span style="color: rgb(0,128,0)"&gt;// The bulk of the clean-up code is implemented in Dispose(bool)
&lt;/span&gt;        &lt;span style="color: rgb(0,0,255)"&gt;protected&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;virtual&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;void&lt;/span&gt; Dispose(&lt;span style="color: rgb(0,0,255)"&gt;bool&lt;/span&gt; disposing)
        {
            &lt;span style="color: rgb(0,0,255)"&gt;if&lt;/span&gt; (disposing)
            {
                &lt;span style="color: rgb(0,128,0)"&gt;// free managed resources
&lt;/span&gt;                ConnectionSettingsStack.Pop(); &lt;span style="color: rgb(0,128,0)"&gt;// Remove the latest server url from the threadstatic stack
&lt;/span&gt;            }
        }
    }
}&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;Maybe I need to explain myself a little on the above code snippet. ConnectionSettingsScope contains a ThreadStatic stack of ConnectionSettings. Each time we create a new ConnectionSettingsScope object it pushes the latest ConnectionSettings class on to its ThreadStatic stack (ThreadStatic means that the stack is static to the thread level, each thread has its own ConnectionSettings stack). Each time we create an HttpRemotable object, the Settings used on it, will be based on the latest ConnectionSettingsScope. &lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;h3&gt;DataService.ashx explained&lt;/h3&gt;

&lt;p&gt;So what happens on the other side of the fence. What happens when I we are creating our HttpRemotable object within a WebServiceSettingsScope? 
  &lt;br /&gt;All method calls are intercepted by the ServiceProxy and a ServiceRequest is sent over to our ServiceHandler. The service request contains all sorts of information of what we are trying to do, it contains information such as the fully qualified name of the underlying real type that has been proxied, the method we want to execute, and all the parameters passed to the method. &lt;/p&gt;

&lt;p&gt;This information is used by the handler to instantiate the object via reflection and call the appropriate method. When method execution completes, the handler constructs a ServiceResponse to send back to the client. This response contains the return value along with the values of any output parameters. &lt;/p&gt;

&lt;p&gt;The actual connection string to the database is stored on the server side. To allow for a multidatabase scenario, the handler is called in the format of DataService.ashx?db=ConnectionStringKeyName&lt;/p&gt;

&lt;p&gt;ConnectionStringKeyName is the key in the web.config of the connectionstring to the database we want to use. &lt;/p&gt;

&lt;p&gt;
  &lt;br /&gt;All objects are created within a DbConnectionSettingsScope region on the service handler. They will be pointing to the database in the selected connectionstring entry of the web.config as described above.&lt;/p&gt;

&lt;p&gt;The DataService.ashx must contain a reference to the dlls that contain the types to be remotely invoked. In this case a single reference to our Dal will suffice. Furthermore, when publishing this web project we must ensure that the referenced dll is also in place. 
  &lt;br /&gt;I can see some are already thinking that adding references is what i wanted to avoid. True to some extent, what i wanted to avoid was the volume of references added. In classic web services I would have typically created one seperate asmx file per data object that i wanted to expose. &lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;The Service Handler supports:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Methods with void result &lt;/li&gt;

  &lt;li&gt;Methods with parameters whose values are serialisable &lt;/li&gt;

  &lt;li&gt;Graceful handling of exceptions and returning them to the client &lt;/li&gt;

  &lt;li&gt;Methods with output parameters &lt;/li&gt;

  &lt;li&gt;Overloaded methods with different parameter signatures. &lt;/li&gt;

  &lt;li&gt;ServiceResponses are gzipped by default to minimise data traffic &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The Service Handler does not support:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Methods whose parameter values are not serialisable &lt;/li&gt;

  &lt;li&gt;Generic methods &lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  &lt;br /&gt;Testing and Performance&lt;/h3&gt;

&lt;p&gt;As mentioned above, the generic service handler uses reflection to reconstruct the underlying object being invoked. In order to assess whether this would mean a serious performance hit or not I created a few tests that benchmark it against equivalent invocations against a microsoft .Net web service. &lt;/p&gt;

&lt;p&gt;The performance is pretty much similar, and in some cases the custom ServiceHandler calls outperform the equivalent calls in web services.  &lt;/p&gt;

&lt;p&gt;The following image contains the various test cases that validate the features supported by the generic Service Handler. 
  &lt;br /&gt;&lt;/p&gt;

&lt;p align="center"&gt;&lt;a href="http://anastasiosyal.com/images/anastasiosyal_com/WindowsLiveWriter/72c3bdee8480_1200A/image_12.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="265" alt="image" src="http://anastasiosyal.com/images/anastasiosyal_com/WindowsLiveWriter/72c3bdee8480_1200A/image_thumb_5.png" width="707" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p align="center"&gt; &lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;h3&gt;Summing it all up&lt;/h3&gt;

&lt;p&gt;This is a solution that you may consider, so long that cross-platform interoperability is not a concern to your application. The remotable objects should only have stateless atomic operations invoked upon them just as the case would be in Web Services.  If you require to have the object alive on the remote tier then Remoting is probably for you. This solution allows you to easily switch between a web service mode and a non webservice mode by literally changing 1 line of code in your application.  This solution minimises redundant coding in a web service tier and allows you to expose your objects over an HTTP channel by simply decorating them with one attribute and deriving from ContextBoundObject. I hope this helps yeou shave off some development time from your projects! &lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;Suggestions, complaints, errors? I will be very happy to hear your opinion and feedback on this. There is a visual studio 2008 solution file that can be downloaded from &lt;a href="http://anastasiosyal.com/DynamicService.zip"&gt;here&lt;/a&gt; to get you started. Happy Coding!&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;Sample solution for this post: &lt;a href="http://anastasiosyal.com/DynamicService.zip"&gt;DynamicService.zip&lt;/a&gt;&lt;/p&gt;&lt;img src="http://anastasiosyal.com/aggbug/11.aspx" width="1" height="1" /&gt;&lt;img src="http://feeds.feedburner.com/~r/anastasiosyal/~4/U3rJdtOAhk8" height="1" width="1"/&gt;</description>
            <dc:creator>Anastasios Yalanopoulos</dc:creator>
            <guid>http://anastasiosyal.com/archive/2008/03/24/expose-your-objects-over-http-with-minimal-coding.aspx</guid>
            <pubDate>Mon, 24 Mar 2008 05:44:16 GMT</pubDate>
            <wfw:comment>http://anastasiosyal.com/comments/11.aspx</wfw:comment>
            <comments>http://anastasiosyal.com/archive/2008/03/24/expose-your-objects-over-http-with-minimal-coding.aspx#feedback</comments>
            <slash:comments>2</slash:comments>
            <wfw:commentRss>http://anastasiosyal.com/comments/commentRss/11.aspx</wfw:commentRss>
        </item>
        <item>
            <title>C# 3.0 Anonymous type support is incomplete</title>
            <link>http://anastasiosyal.com/archive/2007/11/27/c-3.0-anonymous-type-support-is-incomplete.aspx</link>
            <description>&lt;p&gt;For those who have been playing with Linq and getting up to speed with the latest C# 3.0 features, you are most likely aware of the new language feature of &lt;a href="http://weblogs.asp.net/scottgu/archive/2007/05/15/new-orcas-language-feature-anonymous-types.aspx"&gt;Anonymous Types&lt;/a&gt;.     &lt;br /&gt;&lt;/p&gt;  &lt;p&gt;An anonymous type allows us to create and an instance of a an object whose type has not been defined in our code but whose properties are inferred from the object initializer. &lt;/p&gt;  &lt;p&gt;The following example illustrates this by creating an instance of a variable of an unknown type that has 3 properties&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: rgb(0,0,255)"&gt;var&lt;/span&gt; product = &lt;span style="color: rgb(0,0,255)"&gt;new
&lt;/span&gt;{
    Name = &lt;span style="color: rgb(163,21,21)"&gt;"Acme Rocket"&lt;/span&gt;,
    Description = &lt;span style="color: rgb(163,21,21)"&gt;"The quick way to the moon"&lt;/span&gt;,&lt;br /&gt;    Stock = 10&lt;span style="color: rgb(163,21,21)"&gt;
&lt;/span&gt;};&lt;br /&gt;&lt;/pre&gt;

&lt;p&gt;The variable type of product is not defined in our code. It is inferred through &lt;a href="http://www.danielmoth.com/Blog/2007/02/local-variable-type-inference-in-c-30.html"&gt;type inference&lt;/a&gt; and is of a compiler generated anonymous type that has 3 properties whose types again are inferred through type inference.&lt;/p&gt;

&lt;p&gt;
  &lt;br /&gt;Anonymous types are a very powerful feature since they allow for creating &lt;a href="http://msdn2.microsoft.com/en-gb/vcsharp/Aa336758.aspx"&gt;LINQ projections&lt;/a&gt; without the need to define a class containing the projected fields of our query. &lt;/p&gt;

&lt;p&gt;So in the following adapted sample taken from microsoft:&lt;/p&gt;

&lt;pre class="code"&gt;    &lt;span style="color: rgb(0,0,255)"&gt;string&lt;/span&gt;[] words = { &lt;span style="color: rgb(163,21,21)"&gt;"aPPLE"&lt;/span&gt;, &lt;span style="color: rgb(163,21,21)"&gt;"BlUeBeRrY"&lt;/span&gt;, &lt;span style="color: rgb(163,21,21)"&gt;"cHeRry"&lt;/span&gt; };
    &lt;span style="color: rgb(0,0,255)"&gt;var&lt;/span&gt; upperLowerWords =
        (&lt;span style="color: rgb(0,0,255)"&gt;from&lt;/span&gt; w &lt;span style="color: rgb(0,0,255)"&gt;in&lt;/span&gt; words
        &lt;span style="color: rgb(0,0,255)"&gt;select&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; { Upper = w.ToUpper(), Lower = w.ToLower() }).ToList();

    &lt;span style="color: rgb(0,0,255)"&gt;foreach&lt;/span&gt; (&lt;span style="color: rgb(0,0,255)"&gt;var&lt;/span&gt; ul &lt;span style="color: rgb(0,0,255)"&gt;in&lt;/span&gt; upperLowerWords)
    {
        &lt;span style="color: rgb(43,145,175)"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: rgb(163,21,21)"&gt;"Uppercase: {0}, Lowercase: {1}"&lt;/span&gt;, ul.Upper, ul.Lower);
    }&lt;/pre&gt;

&lt;pre class="code"&gt; &lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;upperLowerWords is an instance of an IEnumerable&amp;lt;&lt;em&gt;anonymousType&lt;/em&gt;&amp;gt; and is also intellisensed as such: 

  &lt;br /&gt;

  &lt;br /&gt;&lt;a href="http://anastasiosyal.com/images/anastasiosyal_com/WindowsLiveWriter/C3.0Anonymoustypesupportisincomplete_28BB/image_2.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="197" alt="image" src="http://anastasiosyal.com/images/anastasiosyal_com/WindowsLiveWriter/C3.0Anonymoustypesupportisincomplete_28BB/image_thumb.png" width="653" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;This is all very good. We can create and use anonymous types in our code.&lt;/p&gt;

&lt;p&gt;So what is the problem and why am I saying that anonymous type support is incomplete?&lt;/p&gt;

&lt;p&gt;The problem lays in the fact that &lt;strong&gt;type inference only works on local variables.&lt;/strong&gt; Which means that the anonymous type in our example (and anonymous types in general) is only useful as a strongly bound object in the scope of the procedure in which it has been created. &lt;strong&gt;Anonymous types cannot be returned&lt;/strong&gt; as strongly typed objects in function return values. They can only be returned as objects as the following code shows&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: rgb(0,0,255)"&gt;&lt;br /&gt;object&lt;/span&gt; ReturnAnonymous()
{
    &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; { Name = &lt;span style="color: rgb(163,21,21)"&gt;"Acme Rocket"&lt;/span&gt;, Description = &lt;span style="color: rgb(163,21,21)"&gt;"Quick way to the moon"&lt;/span&gt;, Stock = 10};
}&lt;br /&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;There is an  &lt;a href="http://tomasp.net/blog/cannot-return-anonymous-type-from-method.aspx"&gt;interesting yet dirty workaround for returning  anonymous types&lt;/a&gt; and getting strongly typed access to a return value of type &lt;em&gt;anonymousType&lt;/em&gt; from the calling code. 

  &lt;br /&gt;

  &lt;br /&gt;However, the suggested approach is to define a solid class in your code and use that as the return type instead of returning an anonymous type. In a LINQ Datalayer scenario this means that for each function that returns a projection of Data we would have to define and maintain empty classes that are merely there just to map to the projected object...&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Further reading about this issue&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Msdn forum post and proposed resolutions:  &lt;br /&gt;&lt;a title="http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2434363&amp;amp;SiteID=1" href="http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2434363&amp;amp;SiteID=1"&gt;http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2434363&amp;amp;SiteID=1&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;
  &lt;br /&gt;Rick also talks about this issue in one of his posts (&lt;a title="http://www.west-wind.com/WebLog/posts/33570.aspx" href="http://www.west-wind.com/WebLog/posts/33570.aspx"&gt;http://www.west-wind.com/WebLog/posts/33570.aspx&lt;/a&gt;) 

  &lt;br /&gt;&lt;/p&gt;

&lt;p&gt;I really enjoy the new features of C# 3.0 but not being able to return anonymous types across functions cripples the  potential of this language feature. This appears to be due to limitations in type inference which only works locally, and also seems to be a bit flaky if you ask me, from what I've been reading anyway: 
  &lt;br /&gt;

  &lt;br /&gt;&lt;a title="https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=295134" href="https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=295134"&gt;https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=295134&lt;/a&gt; 

  &lt;br /&gt;

  &lt;br /&gt;&lt;a title="http://blogs.msdn.com/ericlippert/archive/2007/11/05/c-3-0-return-type-inference-does-not-work-on-member-groups.aspx" href="http://blogs.msdn.com/ericlippert/archive/2007/11/05/c-3-0-return-type-inference-does-not-work-on-member-groups.aspx"&gt;http://blogs.msdn.com/ericlippert/archive/2007/11/05/c-3-0-return-type-inference-does-not-work-on-member-groups.aspx&lt;/a&gt;&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt; 

  &lt;br /&gt;Anonymous types even only accessible through local type inference are a really powerful language construct that have added value to LINQ queries (projections) . But I sure do look forward to seeing the &lt;a href="http://msdn2.microsoft.com/en-us/vcsharp/aa336721.aspx"&gt;C# compiler team&lt;/a&gt; unleashing the full potential of type inference and anonymous types by allowing us to return anonymous types as return values in our functions. &lt;/p&gt;&lt;img src="http://anastasiosyal.com/aggbug/10.aspx" width="1" height="1" /&gt;&lt;img src="http://feeds.feedburner.com/~r/anastasiosyal/~4/ettAmlg13CE" height="1" width="1"/&gt;</description>
            <dc:creator>Anastasios Yalanopoulos</dc:creator>
            <guid>http://anastasiosyal.com/archive/2007/11/27/c-3.0-anonymous-type-support-is-incomplete.aspx</guid>
            <pubDate>Tue, 27 Nov 2007 02:54:11 GMT</pubDate>
            <wfw:comment>http://anastasiosyal.com/comments/10.aspx</wfw:comment>
            <comments>http://anastasiosyal.com/archive/2007/11/27/c-3.0-anonymous-type-support-is-incomplete.aspx#feedback</comments>
            <slash:comments>6</slash:comments>
            <wfw:commentRss>http://anastasiosyal.com/comments/commentRss/10.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Yield return and Iterators use case: looping through the days between a date span</title>
            <category>ASP.Net</category>
            <category>C#</category>
            <link>http://anastasiosyal.com/archive/2007/11/15/Yield-return-and-Itirators-use-case-looping-through-the-days.aspx</link>
            <description>&lt;p&gt;I recently found myself in the situation where I had to loop through all the days from a StartDate to an EndDate.&lt;/p&gt;  &lt;p&gt;Sure easy, all you need to do is something like this:&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: rgb(43,145,175)"&gt;DateTime&lt;/span&gt; startDate = &lt;span style="color: rgb(43,145,175)"&gt;DateTime&lt;/span&gt;.Now;
&lt;span style="color: rgb(43,145,175)"&gt;DateTime&lt;/span&gt; endDate = &lt;span style="color: rgb(43,145,175)"&gt;DateTime&lt;/span&gt;.Now.AddDays(3);

&lt;span style="color: rgb(43,145,175)"&gt;DateTime&lt;/span&gt; curDate = startDate;
&lt;span style="color: rgb(0,0,255)"&gt;while&lt;/span&gt; (curDate &amp;lt;= endDate)
{
    &lt;span style="color: rgb(0,128,0)"&gt;//Do Something with curDate ...

&lt;/span&gt;    curDate = curDate.AddDays(1);
}&lt;/pre&gt;

&lt;p&gt;Does the job, but it is not very intuitive in my opinion. It is not that easy to read. 
  &lt;br /&gt;Wouldn't it be so much nicer if we could do something like this: 

  &lt;br /&gt;&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: rgb(43,145,175)"&gt;DayIterator&lt;/span&gt; dayIterator = &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;DayIterator&lt;/span&gt;(startDate, endDate);
&lt;span style="color: rgb(0,0,255)"&gt;foreach&lt;/span&gt; (&lt;span style="color: rgb(43,145,175)"&gt;DateTime&lt;/span&gt; dt &lt;span style="color: rgb(0,0,255)"&gt;in&lt;/span&gt; dayIterator)
{
&lt;span style="color: rgb(0,128,0)"&gt;     //Do Something with dt... &lt;/span&gt;
}&lt;/pre&gt;

&lt;pre class="code"&gt; &lt;/pre&gt;

&lt;p&gt;I think the second version really &lt;strong&gt;shows the intent&lt;/strong&gt; of what we are trying to do and is much more easy to follow and maintain.&lt;/p&gt;

&lt;p&gt;So how do we go about implementing the DayIterator then? As you will see for yourself it really is simple code that makes use of the yield return statement for Iterators.&lt;/p&gt;

&lt;p&gt;Here is the implementation of the DayIterator:&lt;/p&gt;

&lt;pre class="code"&gt;    &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;class&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;DayIterator&lt;/span&gt; : &lt;span style="color: rgb(43,145,175)"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="color: rgb(43,145,175)"&gt;DateTime&lt;/span&gt;&amp;gt;
    {

        &lt;span style="color: rgb(0,0,255)"&gt;private&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;DateTime&lt;/span&gt; _StartDate;
        &lt;span style="color: rgb(0,0,255)"&gt;private&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;DateTime&lt;/span&gt; _EndDate;

        &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; DayIterator(&lt;span style="color: rgb(43,145,175)"&gt;DateTime&lt;/span&gt; startDate, &lt;span style="color: rgb(43,145,175)"&gt;DateTime&lt;/span&gt; endDate)
        {
            _StartDate = startDate;
            _EndDate = endDate;
        }

        &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;IEnumerator&lt;/span&gt;&amp;lt;&lt;span style="color: rgb(43,145,175)"&gt;DateTime&lt;/span&gt;&amp;gt; GetEnumerator()
        {&lt;/pre&gt;

&lt;pre class="code"&gt;            &lt;span style="color: rgb(43,145,175)"&gt;DateTime&lt;/span&gt; currentDate = _StartDate;
            &lt;span style="color: rgb(0,0,255)"&gt;while&lt;/span&gt; (currentDate &amp;lt;= _EndDate) &lt;span style="color: rgb(0,128,0)"&gt;// Note that our Iterator is inclusive of endDate behaving like 'between'&lt;/span&gt;
            {
                &lt;span style="color: rgb(0,0,255)"&gt;yield&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; currentDate; &lt;span style="color: rgb(0,128,0)"&gt;// &amp;lt;-- This is the key line&lt;/span&gt;
                currentDate = currentDate.AddDays(1);
            }
        }

&lt;span style="color: rgb(0,0,255)"&gt;        #region&lt;/span&gt; IEnumerable Members

        System.Collections.&lt;span style="color: rgb(43,145,175)"&gt;IEnumerator&lt;/span&gt; System.Collections.&lt;span style="color: rgb(43,145,175)"&gt;IEnumerable&lt;/span&gt;.GetEnumerator()
        {&lt;/pre&gt;

&lt;pre class="code"&gt;            &lt;span style="color: rgb(0,0,255)"&gt;throw&lt;/span&gt; Exception(&lt;span style="color: rgb(163,21,21)"&gt;"Not Implemented"&lt;/span&gt;);&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;pre class="code"&gt;        }

&lt;span style="color: rgb(0,0,255)"&gt;        #endregion
&lt;/span&gt;    }&lt;/pre&gt;

&lt;pre class="code"&gt; &lt;/pre&gt;

&lt;p&gt;Thats all it takes! Now we have our custom DayIterator class. Now when we do &lt;span style="color: rgb(0,0,255)"&gt;foreach&lt;/span&gt; (&lt;span style="color: rgb(43,145,175)"&gt;DateTime&lt;/span&gt; dt &lt;span style="color: rgb(0,0,255)"&gt;in&lt;/span&gt; dayIterator) what foreach does is it calls GetEnumerator to start the loop. The yield return statement within GetEnumerator returns an instance of a DateTime class so the outer foreach loop starts looping using this as the first element. Each time our code reaches the foreach statement it calls GetEnumerator again &lt;strong&gt;resuming from the last yield return statement&lt;/strong&gt;. When our GetEnumerator function finishes then the outer foreach loop stops looping. So in this example the GetEnumerator will finish when the condition 

  &lt;br /&gt;&lt;span style="color: rgb(0,0,255)"&gt;while&lt;/span&gt; (currentDate &amp;lt;= _EndDate) is not true anymore and therefore the foreach loop will terminate.&lt;/p&gt;

&lt;p&gt;We can also use yield return break within the GetEnumerator implementation if we want to terminate the foreach looping.&lt;/p&gt;

&lt;p&gt;So I guess some of you may be wondering &lt;strong&gt;What's with the two GetEnumerator functions instead of just one?&lt;/strong&gt; Well In this example we want to loop through a collection of DateTime objects for this reason we inherited the DayIterator class from &lt;span style="color: rgb(43,145,175)"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="color: rgb(43,145,175)"&gt;DateTime&lt;/span&gt;&amp;gt;. This requires us to implement both the IEnumerable&amp;lt;DateTime&amp;gt; GetEnumerator() function and the IEnumerbale GetEnumerator (the latter returns only objects and we need not implement)&lt;/p&gt;

&lt;p&gt;Ok, this is all good but does it really work?! Well, lets put it to the test with the following little sample code:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: rgb(43,145,175)"&gt;&lt;br /&gt;DateTime&lt;/span&gt; startDate = &lt;span style="color: rgb(43,145,175)"&gt;DateTime&lt;/span&gt;.Now;
&lt;span style="color: rgb(43,145,175)"&gt;DateTime&lt;/span&gt; endDate = &lt;span style="color: rgb(43,145,175)"&gt;DateTime&lt;/span&gt;.Now.AddDays(5);

&lt;span style="color: rgb(43,145,175)"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: rgb(163,21,21)"&gt;"StartDate: {0:dd MMM yyyy}"&lt;/span&gt;, startDate);
&lt;span style="color: rgb(43,145,175)"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: rgb(163,21,21)"&gt;"EndDate: {0: dd MMM yyyy}"&lt;/span&gt;, endDate);

&lt;span style="color: rgb(43,145,175)"&gt;DayIterator&lt;/span&gt; dayIterator = &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;DayIterator&lt;/span&gt;(startDate, endDate);
&lt;span style="color: rgb(0,0,255)"&gt;foreach&lt;/span&gt; (&lt;span style="color: rgb(43,145,175)"&gt;DateTime&lt;/span&gt; dt &lt;span style="color: rgb(0,0,255)"&gt;in&lt;/span&gt; dayIterator)
{
    &lt;span style="color: rgb(43,145,175)"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: rgb(163,21,21)"&gt;"In foreach: {0:dd MMM yyyy} "&lt;/span&gt;, dt);
}&lt;/pre&gt;

&lt;p&gt;
  &lt;br /&gt;This is what we get:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://anastasiosyal.com/images/anastasiosyal_com/WindowsLiveWriter/YieldreturnandItiratorstoloopthroughthed_1448E/image_6.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="158" alt="image" src="http://anastasiosyal.com/images/anastasiosyal_com/WindowsLiveWriter/YieldreturnandItiratorstoloopthroughthed_1448E/image_thumb_2.png" width="673" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;Now the &lt;span style="color: rgb(43,145,175)"&gt;DayIterator&lt;/span&gt; Class can be easily expanded to include functions such as IsCurrentDayInSameMonthAsPrevious and the resulting code again looks even more elegant in a scenario where while we are looping through the days, we want to do something on when the month changes from one day to the next for example. It is quite straightforward to implement but as an excercise I will leave it up to you to implement :)&lt;/p&gt;

&lt;p&gt;So if you find yourself looping in a for or a while loop, take another careful look at your code, you may be able to use an Iterator and express your code intent in a more clear and concise fashion. Of course this does not mean that we take it to the other extreme abandoning all loops for Iterators! 
  &lt;br /&gt;

  &lt;br /&gt;&lt;strong&gt;Question: &lt;/strong&gt;

  &lt;br /&gt;Can I implement the IEnumerbale GetEnumerator with the same logic as IEnumerable&amp;lt;DateTime&amp;gt; GetEnumerator() but without copying down the same code in two places, how? &lt;/p&gt;
&lt;strong&gt;
  &lt;p&gt;
    &lt;br /&gt;Further Reading: 

    &lt;br /&gt;&lt;a title="http://www.yoda.arachsys.com/csharp/csharp2/iterators.html" href="http://www.yoda.arachsys.com/csharp/csharp2/iterators.html"&gt;http://www.yoda.arachsys.com/csharp/csharp2/iterators.html&lt;/a&gt; 

    &lt;br /&gt;&lt;a title="http://codebetter.com/blogs/david.hayden/archive/2006/10/05/C_2300_-2.0-Iterators-and-Yield-Keyword-_2D00_-Custom-Collection-Enumerators.aspx" href="http://codebetter.com/blogs/david.hayden/archive/2006/10/05/C_2300_-2.0-Iterators-and-Yield-Keyword-_2D00_-Custom-Collection-Enumerators.aspx"&gt;http://codebetter.com/blogs/david.hayden/archive/2006/10/05/C_2300_-2.0-Iterators-and-Yield-Keyword-_2D00_-Custom-Collection-Enumerators.aspx&lt;/a&gt;&lt;/p&gt;
&lt;/strong&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3A%2F%2Fanastasiosyal.com%2Farchive%2F2007%2F11%2F15%2FYield-return-and-Iterators-use-case-looping-through-the-days.aspx"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3A%2F%2Fanastasiosyal.com%2Farchive%2F2007%2F11%2F15%2FYield-return-and-Iterators-use-case-looping-through-the-days.aspx" border="0" /&gt;&lt;/a&gt;&lt;img src="http://anastasiosyal.com/aggbug/9.aspx" width="1" height="1" /&gt;&lt;img src="http://feeds.feedburner.com/~r/anastasiosyal/~4/j07VPCMCE20" height="1" width="1"/&gt;</description>
            <dc:creator>Anastasios Yalanopoulos</dc:creator>
            <guid>http://anastasiosyal.com/archive/2007/11/15/Yield-return-and-Itirators-use-case-looping-through-the-days.aspx</guid>
            <pubDate>Thu, 15 Nov 2007 23:54:28 GMT</pubDate>
            <wfw:comment>http://anastasiosyal.com/comments/9.aspx</wfw:comment>
            <comments>http://anastasiosyal.com/archive/2007/11/15/Yield-return-and-Itirators-use-case-looping-through-the-days.aspx#feedback</comments>
            <slash:comments>1</slash:comments>
            <wfw:commentRss>http://anastasiosyal.com/comments/commentRss/9.aspx</wfw:commentRss>
        </item>
    </channel>
</rss>
