<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/" version="2.0">
  <channel>
    <title>Samurai Programmer.com - Database</title>
    <link>http://www.samuraiprogrammer.com/blog/</link>
    <description>I know kung fu</description>
    <language>en-us</language>
    <copyright>Greg Varveris</copyright>
    <lastBuildDate>Fri, 23 Jul 2010 07:02:43 GMT</lastBuildDate>
    <generator>newtelligence dasBlog 2.3.9074.18820</generator>
    <managingEditor>greg@samuraiprogrammer.com</managingEditor>
    <webMaster>greg@samuraiprogrammer.com</webMaster>
    <item>
      <trackback:ping>http://www.samuraiprogrammer.com/blog/Trackback.aspx?guid=6051d755-1879-46b5-8a5a-9b69b47d461d</trackback:ping>
      <pingback:server>http://www.samuraiprogrammer.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.samuraiprogrammer.com/blog/PermaLink,guid,6051d755-1879-46b5-8a5a-9b69b47d461d.aspx</pingback:target>
      <dc:creator>Greg Varveris</dc:creator>
      <wfw:comment>http://www.samuraiprogrammer.com/blog/CommentView,guid,6051d755-1879-46b5-8a5a-9b69b47d461d.aspx</wfw:comment>
      <wfw:commentRss>http://www.samuraiprogrammer.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=6051d755-1879-46b5-8a5a-9b69b47d461d</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
So, I was working with a customer who is writing their first application using LINQ.
They had previously been bitten by the failure to close and dispose their <a href="http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlconnection.aspx">SqlConnection</a> objects.
This is actually a fairly common problem and usually leads to those pesky <a href="http://www.15seconds.com/issue/040830.htm">SqlExceptions
detailing that there are no connections left in the pool</a>. 
</p>
        <p>
So, since LINQ to SQL abstracts out much of the direct database interaction, they
were concerned about when the underlying SqlConnections are closed. I will walk through
how I answered their question using a few of my favorite tools:
</p>
        <ul>
          <li>
            <a href="http://www.microsoft.com/express/download/">Visual C# Express</a>
          </li>
          <li>
            <a href="http://www.microsoft.com/whdc/devtools/debugging/installx86.mspx#a">Debugging
Tools for Windows</a>
          </li>
        </ul>
        <p>
To start off, I created a simple SQL Table called Users:
</p>
        <p>
          <a href="http://samuraiprogrammer.com/community/blogimages/LINQDataContextConnections_1164C/UserTable.png">
            <img style="display: block; float: none; margin-left: auto; margin-right: auto" title="UserTable" border="0" alt="UserTable" src="http://samuraiprogrammer.com/community/blogimages/LINQDataContextConnections_1164C/UserTable_thumb.png" width="288" height="88" />
          </a>
        </p>
        <p>
Then, I created a simple LINQ to SQL dbml:
</p>
        <p>
          <a href="http://samuraiprogrammer.com/community/blogimages/LINQDataContextConnections_1164C/Linq2SqlDBML.png">
            <img style="display: block; float: none; margin-left: auto; margin-right: auto" title="Linq2SqlDBML" border="0" alt="Linq2SqlDBML" src="http://samuraiprogrammer.com/community/blogimages/LINQDataContextConnections_1164C/Linq2SqlDBML_thumb.png" width="193" height="155" />
          </a>
        </p>
        <p>
Now that the plumbing is in place, I can write some simple code to return the data
from the table and display it to the console window:
</p>
        <div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; font-size: 8pt; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
          <div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet">
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum1"> 1:</span> LinqConnectionSampleDataContext
db = </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum2"> 2:</span>
              <span style="color: #0000ff">new</span> LinqConnectionSampleDataContext();</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum3"> 3:</span>  </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum4"> 4:</span> Table&lt;User&gt;
users = db.GetTable&lt;User&gt;();</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum5"> 5:</span>  </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum6"> 6:</span> IQueryable&lt;User&gt;
userQuery =</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum7"> 7:</span> from
user <span style="color: #0000ff">in</span> users</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum8"> 8:</span> orderby
user.firstName</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum9"> 9:</span> select
user;</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum10"> 10:</span>
            </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum11"> 11:</span>  </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum12"> 12:</span>
              <span style="color: #0000ff">foreach</span> (User
user <span style="color: #0000ff">in</span> userQuery)</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum13"> 13:</span> {</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum14"> 14:</span>  </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum15"> 15:</span> Console.WriteLine(<span style="color: #006080">"ID={0},
First Name={1}"</span>, </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum16"> 16:</span> user.id, </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum17"> 17:</span> user.firstName);</pre>
            <!--CRLF-->
          </div>
        </div>
        <p>
So, now when the application is executed, the output is as follows: 
</p>
        <p>
          <a href="http://samuraiprogrammer.com/community/blogimages/LINQDataContextConnections_1164C/ConsoleSampleOutput.png">
            <img style="display: block; float: none; margin-left: auto; margin-right: auto" title="ConsoleSampleOutput" border="0" alt="ConsoleSampleOutput" src="http://samuraiprogrammer.com/community/blogimages/LINQDataContextConnections_1164C/ConsoleSampleOutput_thumb.png" width="561" height="91" />
          </a>
        </p>
        <p>
So, since Linq to Sql uses an underlying SqlConnection to do its work, we can set
a breakpoint on the Close() method of that class in WinDBG. If you are unfamiliar
with this great debugging tool, you can find a simple walkthrough on how to set it
up <a href="http://blogs.msdn.com/johan/archive/2007/11/13/getting-started-with-windbg-part-i.aspx">here</a>. 
</p>
        <p>
There are a number of ways to set a breakpoint in managed code in WinDBG. Here are
the steps that I followed:
</p>
        <h4>Step 1. Launch WinDBG and attach to the process in question.
</h4>
        <p>
          <a href="http://samuraiprogrammer.com/community/blogimages/LINQDataContextConnections_1164C/Windbg_AttachToProcess_RedCircle.png">
            <img title="Windbg_AttachToProcess_RedCircle" border="0" alt="Windbg_AttachToProcess_RedCircle" src="http://samuraiprogrammer.com/community/blogimages/LINQDataContextConnections_1164C/Windbg_AttachToProcess_RedCircle_thumb.png" width="428" height="626" />
          </a>
        </p>
        <h4>Step 2. Load the SOS extension into WinDBG by executing:
</h4>
        <p>
          <strong>.loadby sos mscorwks</strong>
        </p>
        <p>
Step 3. Set the managed breakpoint using the !bpmd command. For this step, the !bpmd
command accepts a variety of parameters. Basically, you can pass it either:
</p>
        <ul>
          <li>
            <p>
MethodDescr address.
</p>
          </li>
          <li>
            <p>
Combination of Module Name and Managed Function Name
</p>
          </li>
        </ul>
        <p>
I chose the latter method because it’s relatively quick and I knew exactly what I
wanted. So, the syntax for this method is:
</p>
        <blockquote>
          <p>
!bpmd &lt;module name&gt; &lt;managed function name&gt;
</p>
        </blockquote>
        <p>
You can get the module name from visiting the <a href="http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlconnection.aspx">SqlConnection
page up on MSDN</a>. On this page, we can get the module name and the namespace to
the class:
</p>
        <p>
          <a href="http://samuraiprogrammer.com/community/blogimages/LINQDataContextConnections_1164C/MSDN_sqlconnection.png">
            <img title="MSDN_sqlconnection" border="0" alt="MSDN_sqlconnection" src="http://samuraiprogrammer.com/community/blogimages/LINQDataContextConnections_1164C/MSDN_sqlconnection_thumb.png" width="425" height="136" />
          </a>
        </p>
        <p>
From this, we can get both parameters necessary:
</p>
        <ul>
          <li>
Module Name: <strong>System.Data.dll</strong></li>
          <li>
Managed Function Name: <strong>System.Data.SqlClient.SqlConnection.Close</strong></li>
        </ul>
        <p>
So, our command in WinDBG becomes:
</p>
        <blockquote>
          <div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; font-size: 8pt; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
            <div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet">
              <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
                <span style="color: #606060" id="lnum1"> 1:</span> !bpmd
System.Data.dll </pre>
              <!--CRLF-->
              <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
                <span style="color: #606060" id="lnum2"> 2:</span> System.Data.SqlClient.SqlConnection.Close</pre>
              <!--CRLF-->
            </div>
          </div>
        </blockquote>
        <p>
Once you enter in this command, you should get output similar to the following in
the WinDBG window:
</p>
        <pre>0:014&gt; !bpmd System.Data.dll System.Data.SqlClient.SqlConnection.Close
Found 1 methods...
MethodDesc = 544a0418
Setting breakpoint: bp 5455DC80 [System.Data.SqlClient.SqlConnection.Close()]</pre>
        <h4>Step 4. “Go” in the debugger and wait for your breakpoint to be hit. 
</h4>
        <p>
For this, the command is simply “g”.
</p>
        <pre>0:014&gt; g</pre>
        <p>
Eventually, your breakpoint will be hit in the debugger and you should get output
similar to the following:
</p>
        <pre>Breakpoint 0 hit
eax=5457da68 ebx=04d7e9dc ecx=0185cd30 edx=018e56b0 esi=01870d80 edi=04d7e9a4
eip=5455dc80 esp=04d7e860 ebp=04d7e868 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
System_Data_ni+0xcdc80:
5455dc80 55              push    ebp</pre>
        <h4>Step 5. Print out the call-stack. 
</h4>
        <p>
The command to print out the call stack in SOS and WinDBG is “!clrstack”:
</p>
        <pre>0:008&gt; !clrstack</pre>
        <p>
This will print out the managed call stack, which turns out to be:
</p>
        <pre>OS Thread Id: 0x1d70 (8)
ESP       EIP     
04d7e860 5455dc80 System.Data.SqlClient.SqlConnection.Close()
04d7e864 77e20586 System.Data.Linq.SqlClient.SqlConnectionManager
                    .CloseConnection()
04d7e870 77e20554 System.Data.Linq.SqlClient.SqlConnectionManager
                    .ReleaseConnection(...)
04d7e87c 77e1da35 System.Data.Linq.SqlClient.
        ObjectReaderCompiler+ObjectReaderSession`1[...].Dispose()
04d7e888 77e1ddac System.Data.Linq.SqlClient.
        ObjectReaderCompiler+ObjectReaderSession`1[...].CheckNextResults()
04d7e894 77e1df2c System.Data.Linq.SqlClient.
        ObjectReaderCompiler+ObjectReaderBase`1[...].Read()
04d7e8a0 77e1ea2d System.Data.Linq.SqlClient.
        ObjectReaderCompiler+ObjectReader`2[...].MoveNext()
04d7e8ac 004f1a12 LINQ.SqlConnection.Program.Main(System.String[])</pre>
        <p>
So, if you’re having trouble parsing this, the take away here is that when you iterate
through a Linq resultset and you get to the end, the ObjectReaderSession will automatically
close the Connection to the database.
</p>
        <p>
Now, this is a simple HelloWorld code sample for retrieving a result-set and there
are obviously a number of ways to do the same thing. The customer’s code was closer
to the following:
</p>
        <p>
        </p>
        <p>
        </p>
        <p>
        </p>
        <div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; font-size: 8pt; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
          <div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet">
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum1"> 1:</span>
              <span style="color: #0000ff">using</span> (IEnumerator&lt;User&gt;
enumerator = </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum2"> 2:</span> context.ExecuteQuery&lt;User&gt;(sqlStatement).GetEnumerator())</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum3"> 3:</span> {</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum4"> 4:</span>  </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum5"> 5:</span>
              <span style="color: #0000ff">while</span> (enumerator.MoveNext())</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum6"> 6:</span> {</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum7"> 7:</span>  </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum8"> 8:</span>
              <span style="color: #008000">//
Do something here</span>
            </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum9"> 9:</span>  </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum10"> 10:</span> }</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum11"> 11:</span>  </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum12"> 12:</span> }</pre>
            <!--CRLF-->
          </div>
        </div>
        <p>
In this situation, we get an IEnumerator&lt;T&gt; back from the database call and
iterate through it. <strong>Now, this part is very important.</strong> If you are
iterating through the result set to completion – the connection will be closed the
same as the above. However, if you do something like this:
</p>
        <div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; font-size: 8pt; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
          <div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet">
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum1"> 1:</span>
              <span style="color: #0000ff">using</span> (IEnumerator&lt;User&gt;
enumerator = </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum2"> 2:</span> db.ExecuteQuery&lt;User&gt;(sqlStatement).GetEnumerator())</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum3"> 3:</span> {</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum4"> 4:</span>
              <span style="color: #0000ff">while</span> (enumerator.MoveNext())</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum5"> 5:</span> {</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum6"> 6:</span>  </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum7"> 7:</span> Console.WriteLine(<span style="color: #006080">"ID={0},
First Name={1}"</span>, </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum8"> 8:</span> enumerator.Current.id, </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum9"> 9:</span> enumerator.Current.firstName);</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum10"> 10:</span>
            </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum11"> 11:</span>
              <span style="color: #008000">//
Stop iterating after this record.</span>
            </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum12"> 12:</span>
              <span style="color: #0000ff">break</span>;</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum13"> 13:</span>  </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum14"> 14:</span> }</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum15"> 15:</span>  </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum16"> 16:</span> }</pre>
            <!--CRLF-->
          </div>
        </div>
        <p>
Please note the “break” statement. Essentially, if you are NOT iterating through to
completion, the call stack looks like:
</p>
        <pre>OS Thread Id: 0x251c (11)
ESP       EIP     
0522e73c 5455dc80 System.Data.SqlClient.SqlConnection.
                    Close()
0522e740 77e20586 System.Data.Linq.SqlClient.SqlConnectionManager.
                    CloseConnection()
0522e74c 77e20554 System.Data.Linq.SqlClient.SqlConnectionManager.
                    ReleaseConnection(...)
0522e758 77e1da35 System.Data.Linq.SqlClient.ObjectReaderCompiler+
                    ObjectReaderSession`1[...].Dispose()
0522e764 77e1ea12 System.Data.Linq.SqlClient.ObjectReaderCompiler+
                    ObjectReader`2[...].Dispose()
0522e768 00691bde LINQ.SqlConnection.Program.Main(System.String[])</pre>
        <p>
          <strong>The connection will NOT be closed until you call Dispose() on the ObjectReader
(IEnumerable) object.</strong> This means that if you happen to write some code without
the Using… statement when returning data like this:
</p>
        <div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; font-size: 8pt; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
          <div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet">
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum1"> 1:</span> IEnumerator&lt;User&gt;
enumerator =</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum2"> 2:</span> db.ExecuteQuery&lt;User&gt;(sqlStatement).GetEnumerator();</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum3"> 3:</span>  </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum4"> 4:</span>
              <span style="color: #0000ff">while</span> (enumerator.MoveNext())</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum5"> 5:</span> {</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum6"> 6:</span>  </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum7"> 7:</span> Console.WriteLine(<span style="color: #006080">"ID={0},
First Name={1}"</span>,</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum8"> 8:</span> enumerator.Current.id,</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum9"> 9:</span> enumerator.Current.firstName);</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum10"> 10:</span>  </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum11"> 11:</span>
              <span style="color: #008000">//
Stop iterating after this record.</span>
            </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum12"> 12:</span>
              <span style="color: #0000ff">break</span>;</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum13"> 13:</span>  </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum14"> 14:</span> }</pre>
            <!--CRLF-->
          </div>
        </div>
        <p>
The SqlConnection.Close() method will <strong>NOT</strong> be called. This is because
you have full control over the lifetime of the IEnumerator&lt;T&gt; object and you
should know when you are done with it. 
</p>
        <p>
Now, along those lines, you may be asking yourself – what if I did something like
this:
</p>
        <div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; font-size: 8pt; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
          <div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet">
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum1"> 1:</span> LinqConnectionSampleDataContext
db = </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum2"> 2:</span>
              <span style="color: #0000ff">new</span> LinqConnectionSampleDataContext();</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum3"> 3:</span>  </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum4"> 4:</span> Table&lt;User&gt;
users = db.GetTable&lt;User&gt;();</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum5"> 5:</span>  </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum6"> 6:</span> IQueryable&lt;User&gt;
userQuery =</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum7"> 7:</span> from
user <span style="color: #0000ff">in</span> users</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum8"> 8:</span> orderby
user.firstName</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum9"> 9:</span> select
user;</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum10"> 10:</span>
            </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum11"> 11:</span>  </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum12"> 12:</span>
              <span style="color: #0000ff">foreach</span> (User
user <span style="color: #0000ff">in</span> userQuery)</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum13"> 13:</span> {</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum14"> 14:</span>  </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum15"> 15:</span> Console.WriteLine(<span style="color: #006080">"ID={0},
First Name={1}"</span>, </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum16"> 16:</span> user.id, </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum17"> 17:</span> user.firstName);</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum18"> 18:</span>  </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum19"> 19:</span>
              <span style="color: #0000ff">break</span>;</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum20"> 20:</span> }</pre>
            <!--CRLF-->
          </div>
        </div>
        <p>
Where you break before you iterate through to completion? In that situation, Dispose()
will still be called on the IQueryable&lt;T&gt; object. How? Because of a compile-time
optimization we do. We insert a finally statement after the userQuery has been used.
This compiles down to (in IL):
</p>
        <pre> try{<br />
L_005d: br.s L_0084 L_005f: ldloc.s CS$5$0002 L_0061: callvirt instance !0...get_Current()
L_0066: stloc.3 L_0067: ldstr "ID={0}, First Name={1}" L_006c: ldloc.3 L_006d:
callvirt instance int32 LINQ.SqlConnection.User::get_id() L_0072: box int32 L_0077:
ldloc.3 L_0078: callvirt instance string LINQ.SqlConnection.User::get_firstName()
L_007d: call void [mscorlib]System.Console::WriteLine(string, object, object) L_0082:
br.s L_008d L_0084: ldloc.s CS$5$0002 L_0086: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext()
L_008b: brtrue.s L_005f L_008d: leave.s L_009b<br />
}finally{<br />
L_008f: ldloc.s CS$5$0002 L_0091: brfalse.s L_009a L_0093: ldloc.s CS$5$0002 L_0095:
callvirt instance void [mscorlib]System.IDisposable::Dispose() L_009a: endfinally<br />
} L_009b: ret .try L_005d to L_008f finally handler L_008f to L_009b</pre>
        <p>
The text in red is my emphasis. So, the moral of this story, when you take control
of the data yourself, you MUST call dispose on the IEnumerable&lt;T&gt; object when
you are done with it.
</p>
        <p>
Enjoy!
</p>
      </body>
      <title>LINQ: When are my database connections closed?</title>
      <guid isPermaLink="false">http://www.samuraiprogrammer.com/blog/PermaLink,guid,6051d755-1879-46b5-8a5a-9b69b47d461d.aspx</guid>
      <link>http://www.samuraiprogrammer.com/blog/2010/07/23/LINQWhenAreMyDatabaseConnectionsClosed.aspx</link>
      <pubDate>Fri, 23 Jul 2010 07:02:43 GMT</pubDate>
      <description>&lt;p&gt;
So, I was working with a customer who is writing their first application using LINQ.
They had previously been bitten by the failure to close and dispose their &lt;a href="http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlconnection.aspx"&gt;SqlConnection&lt;/a&gt; objects.
This is actually a fairly common problem and usually leads to those pesky &lt;a href="http://www.15seconds.com/issue/040830.htm"&gt;SqlExceptions
detailing that there are no connections left in the pool&lt;/a&gt;. 
&lt;/p&gt;
&lt;p&gt;
So, since LINQ to SQL abstracts out much of the direct database interaction, they
were concerned about when the underlying SqlConnections are closed. I will walk through
how I answered their question using a few of my favorite tools:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;a href="http://www.microsoft.com/express/download/"&gt;Visual C# Express&lt;/a&gt; 
&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://www.microsoft.com/whdc/devtools/debugging/installx86.mspx#a"&gt;Debugging
Tools for Windows&lt;/a&gt; 
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
To start off, I created a simple SQL Table called Users:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://samuraiprogrammer.com/community/blogimages/LINQDataContextConnections_1164C/UserTable.png"&gt;&lt;img style="display: block; float: none; margin-left: auto; margin-right: auto" title="UserTable" border="0" alt="UserTable" src="http://samuraiprogrammer.com/community/blogimages/LINQDataContextConnections_1164C/UserTable_thumb.png" width="288" height="88" /&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
Then, I created a simple LINQ to SQL dbml:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://samuraiprogrammer.com/community/blogimages/LINQDataContextConnections_1164C/Linq2SqlDBML.png"&gt;&lt;img style="display: block; float: none; margin-left: auto; margin-right: auto" title="Linq2SqlDBML" border="0" alt="Linq2SqlDBML" src="http://samuraiprogrammer.com/community/blogimages/LINQDataContextConnections_1164C/Linq2SqlDBML_thumb.png" width="193" height="155" /&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
Now that the plumbing is in place, I can write some simple code to return the data
from the table and display it to the console window:
&lt;/p&gt;
&lt;div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; font-size: 8pt; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;
&lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum1"&gt; 1:&lt;/span&gt; LinqConnectionSampleDataContext
db = &lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum2"&gt; 2:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; LinqConnectionSampleDataContext();&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum3"&gt; 3:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum4"&gt; 4:&lt;/span&gt; Table&amp;lt;User&amp;gt;
users = db.GetTable&amp;lt;User&amp;gt;();&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum5"&gt; 5:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum6"&gt; 6:&lt;/span&gt; IQueryable&amp;lt;User&amp;gt;
userQuery =&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum7"&gt; 7:&lt;/span&gt; from
user &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; users&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum8"&gt; 8:&lt;/span&gt; orderby
user.firstName&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum9"&gt; 9:&lt;/span&gt; select
user;&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum10"&gt; 10:&lt;/span&gt; &lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum11"&gt; 11:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum12"&gt; 12:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;foreach&lt;/span&gt; (User
user &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; userQuery)&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum13"&gt; 13:&lt;/span&gt; {&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum14"&gt; 14:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum15"&gt; 15:&lt;/span&gt; Console.WriteLine(&lt;span style="color: #006080"&gt;&amp;quot;ID={0},
First Name={1}&amp;quot;&lt;/span&gt;, &lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum16"&gt; 16:&lt;/span&gt; user.id, &lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum17"&gt; 17:&lt;/span&gt; user.firstName);&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;
So, now when the application is executed, the output is as follows: 
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://samuraiprogrammer.com/community/blogimages/LINQDataContextConnections_1164C/ConsoleSampleOutput.png"&gt;&lt;img style="display: block; float: none; margin-left: auto; margin-right: auto" title="ConsoleSampleOutput" border="0" alt="ConsoleSampleOutput" src="http://samuraiprogrammer.com/community/blogimages/LINQDataContextConnections_1164C/ConsoleSampleOutput_thumb.png" width="561" height="91" /&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
So, since Linq to Sql uses an underlying SqlConnection to do its work, we can set
a breakpoint on the Close() method of that class in WinDBG. If you are unfamiliar
with this great debugging tool, you can find a simple walkthrough on how to set it
up &lt;a href="http://blogs.msdn.com/johan/archive/2007/11/13/getting-started-with-windbg-part-i.aspx"&gt;here&lt;/a&gt;. 
&lt;/p&gt;
&lt;p&gt;
There are a number of ways to set a breakpoint in managed code in WinDBG. Here are
the steps that I followed:
&lt;/p&gt;
&lt;h4&gt;Step 1. Launch WinDBG and attach to the process in question.
&lt;/h4&gt;
&lt;p&gt;
&lt;a href="http://samuraiprogrammer.com/community/blogimages/LINQDataContextConnections_1164C/Windbg_AttachToProcess_RedCircle.png"&gt;&lt;img title="Windbg_AttachToProcess_RedCircle" border="0" alt="Windbg_AttachToProcess_RedCircle" src="http://samuraiprogrammer.com/community/blogimages/LINQDataContextConnections_1164C/Windbg_AttachToProcess_RedCircle_thumb.png" width="428" height="626" /&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;h4&gt;Step 2. Load the SOS extension into WinDBG by executing:
&lt;/h4&gt;
&lt;p&gt;
&lt;strong&gt;.loadby sos mscorwks&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
Step 3. Set the managed breakpoint using the !bpmd command. For this step, the !bpmd
command accepts a variety of parameters. Basically, you can pass it either:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;
MethodDescr address.
&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
Combination of Module Name and Managed Function Name
&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
I chose the latter method because it’s relatively quick and I knew exactly what I
wanted. So, the syntax for this method is:
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
!bpmd &amp;lt;module name&amp;gt; &amp;lt;managed function name&amp;gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
You can get the module name from visiting the &lt;a href="http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlconnection.aspx"&gt;SqlConnection
page up on MSDN&lt;/a&gt;. On this page, we can get the module name and the namespace to
the class:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://samuraiprogrammer.com/community/blogimages/LINQDataContextConnections_1164C/MSDN_sqlconnection.png"&gt;&lt;img title="MSDN_sqlconnection" border="0" alt="MSDN_sqlconnection" src="http://samuraiprogrammer.com/community/blogimages/LINQDataContextConnections_1164C/MSDN_sqlconnection_thumb.png" width="425" height="136" /&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
From this, we can get both parameters necessary:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Module Name: &lt;strong&gt;System.Data.dll&lt;/strong&gt; 
&lt;/li&gt;
&lt;li&gt;
Managed Function Name: &lt;strong&gt;System.Data.SqlClient.SqlConnection.Close&lt;/strong&gt; 
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
So, our command in WinDBG becomes:
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; font-size: 8pt; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;
&lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum1"&gt; 1:&lt;/span&gt; !bpmd
System.Data.dll &lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum2"&gt; 2:&lt;/span&gt; System.Data.SqlClient.SqlConnection.Close&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
Once you enter in this command, you should get output similar to the following in
the WinDBG window:
&lt;/p&gt;
&lt;pre&gt;0:014&amp;gt; !bpmd System.Data.dll System.Data.SqlClient.SqlConnection.Close
Found 1 methods...
MethodDesc = 544a0418
Setting breakpoint: bp 5455DC80 [System.Data.SqlClient.SqlConnection.Close()]&lt;/pre&gt;
&lt;h4&gt;Step 4. “Go” in the debugger and wait for your breakpoint to be hit. 
&lt;/h4&gt;
&lt;p&gt;
For this, the command is simply “g”.
&lt;/p&gt;
&lt;pre&gt;0:014&amp;gt; g&lt;/pre&gt;
&lt;p&gt;
Eventually, your breakpoint will be hit in the debugger and you should get output
similar to the following:
&lt;/p&gt;
&lt;pre&gt;Breakpoint 0 hit
eax=5457da68 ebx=04d7e9dc ecx=0185cd30 edx=018e56b0 esi=01870d80 edi=04d7e9a4
eip=5455dc80 esp=04d7e860 ebp=04d7e868 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
System_Data_ni+0xcdc80:
5455dc80 55              push    ebp&lt;/pre&gt;
&lt;h4&gt;Step 5. Print out the call-stack. 
&lt;/h4&gt;
&lt;p&gt;
The command to print out the call stack in SOS and WinDBG is “!clrstack”:
&lt;/p&gt;
&lt;pre&gt;0:008&amp;gt; !clrstack&lt;/pre&gt;
&lt;p&gt;
This will print out the managed call stack, which turns out to be:
&lt;/p&gt;
&lt;pre&gt;OS Thread Id: 0x1d70 (8)
ESP       EIP     
04d7e860 5455dc80 System.Data.SqlClient.SqlConnection.Close()
04d7e864 77e20586 System.Data.Linq.SqlClient.SqlConnectionManager
                    .CloseConnection()
04d7e870 77e20554 System.Data.Linq.SqlClient.SqlConnectionManager
                    .ReleaseConnection(...)
04d7e87c 77e1da35 System.Data.Linq.SqlClient.
        ObjectReaderCompiler+ObjectReaderSession`1[...].Dispose()
04d7e888 77e1ddac System.Data.Linq.SqlClient.
        ObjectReaderCompiler+ObjectReaderSession`1[...].CheckNextResults()
04d7e894 77e1df2c System.Data.Linq.SqlClient.
        ObjectReaderCompiler+ObjectReaderBase`1[...].Read()
04d7e8a0 77e1ea2d System.Data.Linq.SqlClient.
        ObjectReaderCompiler+ObjectReader`2[...].MoveNext()
04d7e8ac 004f1a12 LINQ.SqlConnection.Program.Main(System.String[])&lt;/pre&gt;
&lt;p&gt;
So, if you’re having trouble parsing this, the take away here is that when you iterate
through a Linq resultset and you get to the end, the ObjectReaderSession will automatically
close the Connection to the database.
&lt;/p&gt;
&lt;p&gt;
Now, this is a simple HelloWorld code sample for retrieving a result-set and there
are obviously a number of ways to do the same thing. The customer’s code was closer
to the following:
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; font-size: 8pt; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;
&lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum1"&gt; 1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;using&lt;/span&gt; (IEnumerator&amp;lt;User&amp;gt;
enumerator = &lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum2"&gt; 2:&lt;/span&gt; context.ExecuteQuery&amp;lt;User&amp;gt;(sqlStatement).GetEnumerator())&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum3"&gt; 3:&lt;/span&gt; {&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum4"&gt; 4:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum5"&gt; 5:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;while&lt;/span&gt; (enumerator.MoveNext())&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum6"&gt; 6:&lt;/span&gt; {&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum7"&gt; 7:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum8"&gt; 8:&lt;/span&gt; &lt;span style="color: #008000"&gt;//
Do something here&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum9"&gt; 9:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum10"&gt; 10:&lt;/span&gt; }&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum11"&gt; 11:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum12"&gt; 12:&lt;/span&gt; }&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;
In this situation, we get an IEnumerator&amp;lt;T&amp;gt; back from the database call and
iterate through it. &lt;strong&gt;Now, this part is very important.&lt;/strong&gt; If you are
iterating through the result set to completion – the connection will be closed the
same as the above. However, if you do something like this:
&lt;/p&gt;
&lt;div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; font-size: 8pt; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;
&lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum1"&gt; 1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;using&lt;/span&gt; (IEnumerator&amp;lt;User&amp;gt;
enumerator = &lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum2"&gt; 2:&lt;/span&gt; db.ExecuteQuery&amp;lt;User&amp;gt;(sqlStatement).GetEnumerator())&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum3"&gt; 3:&lt;/span&gt; {&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum4"&gt; 4:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;while&lt;/span&gt; (enumerator.MoveNext())&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum5"&gt; 5:&lt;/span&gt; {&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum6"&gt; 6:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum7"&gt; 7:&lt;/span&gt; Console.WriteLine(&lt;span style="color: #006080"&gt;&amp;quot;ID={0},
First Name={1}&amp;quot;&lt;/span&gt;, &lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum8"&gt; 8:&lt;/span&gt; enumerator.Current.id, &lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum9"&gt; 9:&lt;/span&gt; enumerator.Current.firstName);&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum10"&gt; 10:&lt;/span&gt; &lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum11"&gt; 11:&lt;/span&gt; &lt;span style="color: #008000"&gt;//
Stop iterating after this record.&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum12"&gt; 12:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;break&lt;/span&gt;;&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum13"&gt; 13:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum14"&gt; 14:&lt;/span&gt; }&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum15"&gt; 15:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum16"&gt; 16:&lt;/span&gt; }&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;
Please note the “break” statement. Essentially, if you are NOT iterating through to
completion, the call stack looks like:
&lt;/p&gt;
&lt;pre&gt;OS Thread Id: 0x251c (11)
ESP       EIP     
0522e73c 5455dc80 System.Data.SqlClient.SqlConnection.
                    Close()
0522e740 77e20586 System.Data.Linq.SqlClient.SqlConnectionManager.
                    CloseConnection()
0522e74c 77e20554 System.Data.Linq.SqlClient.SqlConnectionManager.
                    ReleaseConnection(...)
0522e758 77e1da35 System.Data.Linq.SqlClient.ObjectReaderCompiler+
                    ObjectReaderSession`1[...].Dispose()
0522e764 77e1ea12 System.Data.Linq.SqlClient.ObjectReaderCompiler+
                    ObjectReader`2[...].Dispose()
0522e768 00691bde LINQ.SqlConnection.Program.Main(System.String[])&lt;/pre&gt;
&lt;p&gt;
&lt;strong&gt;The connection will NOT be closed until you call Dispose() on the ObjectReader
(IEnumerable) object.&lt;/strong&gt; This means that if you happen to write some code without
the Using… statement when returning data like this:
&lt;/p&gt;
&lt;div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; font-size: 8pt; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;
&lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum1"&gt; 1:&lt;/span&gt; IEnumerator&amp;lt;User&amp;gt;
enumerator =&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum2"&gt; 2:&lt;/span&gt; db.ExecuteQuery&amp;lt;User&amp;gt;(sqlStatement).GetEnumerator();&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum3"&gt; 3:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum4"&gt; 4:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;while&lt;/span&gt; (enumerator.MoveNext())&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum5"&gt; 5:&lt;/span&gt; {&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum6"&gt; 6:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum7"&gt; 7:&lt;/span&gt; Console.WriteLine(&lt;span style="color: #006080"&gt;&amp;quot;ID={0},
First Name={1}&amp;quot;&lt;/span&gt;,&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum8"&gt; 8:&lt;/span&gt; enumerator.Current.id,&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum9"&gt; 9:&lt;/span&gt; enumerator.Current.firstName);&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum10"&gt; 10:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum11"&gt; 11:&lt;/span&gt; &lt;span style="color: #008000"&gt;//
Stop iterating after this record.&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum12"&gt; 12:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;break&lt;/span&gt;;&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum13"&gt; 13:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum14"&gt; 14:&lt;/span&gt; }&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;
The SqlConnection.Close() method will &lt;strong&gt;NOT&lt;/strong&gt; be called. This is because
you have full control over the lifetime of the IEnumerator&amp;lt;T&amp;gt; object and you
should know when you are done with it. 
&lt;/p&gt;
&lt;p&gt;
Now, along those lines, you may be asking yourself – what if I did something like
this:
&lt;/p&gt;
&lt;div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; font-size: 8pt; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;
&lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum1"&gt; 1:&lt;/span&gt; LinqConnectionSampleDataContext
db = &lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum2"&gt; 2:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; LinqConnectionSampleDataContext();&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum3"&gt; 3:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum4"&gt; 4:&lt;/span&gt; Table&amp;lt;User&amp;gt;
users = db.GetTable&amp;lt;User&amp;gt;();&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum5"&gt; 5:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum6"&gt; 6:&lt;/span&gt; IQueryable&amp;lt;User&amp;gt;
userQuery =&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum7"&gt; 7:&lt;/span&gt; from
user &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; users&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum8"&gt; 8:&lt;/span&gt; orderby
user.firstName&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum9"&gt; 9:&lt;/span&gt; select
user;&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum10"&gt; 10:&lt;/span&gt; &lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum11"&gt; 11:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum12"&gt; 12:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;foreach&lt;/span&gt; (User
user &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; userQuery)&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum13"&gt; 13:&lt;/span&gt; {&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum14"&gt; 14:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum15"&gt; 15:&lt;/span&gt; Console.WriteLine(&lt;span style="color: #006080"&gt;&amp;quot;ID={0},
First Name={1}&amp;quot;&lt;/span&gt;, &lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum16"&gt; 16:&lt;/span&gt; user.id, &lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum17"&gt; 17:&lt;/span&gt; user.firstName);&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum18"&gt; 18:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum19"&gt; 19:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;break&lt;/span&gt;;&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum20"&gt; 20:&lt;/span&gt; }&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;
Where you break before you iterate through to completion? In that situation, Dispose()
will still be called on the IQueryable&amp;lt;T&amp;gt; object. How? Because of a compile-time
optimization we do. We insert a finally statement after the userQuery has been used.
This compiles down to (in IL):
&lt;/p&gt;
&lt;pre&gt; try{&lt;br /&gt;
L_005d: br.s L_0084 L_005f: ldloc.s CS$5$0002 L_0061: callvirt instance !0...get_Current()
L_0066: stloc.3 L_0067: ldstr &amp;quot;ID={0}, First Name={1}&amp;quot; L_006c: ldloc.3 L_006d:
callvirt instance int32 LINQ.SqlConnection.User::get_id() L_0072: box int32 L_0077:
ldloc.3 L_0078: callvirt instance string LINQ.SqlConnection.User::get_firstName()
L_007d: call void [mscorlib]System.Console::WriteLine(string, object, object) L_0082:
br.s L_008d L_0084: ldloc.s CS$5$0002 L_0086: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext()
L_008b: brtrue.s L_005f L_008d: leave.s L_009b&lt;br /&gt;
}finally{&lt;br /&gt;
L_008f: ldloc.s CS$5$0002 L_0091: brfalse.s L_009a L_0093: ldloc.s CS$5$0002 L_0095:
callvirt instance void [mscorlib]System.IDisposable::Dispose() L_009a: endfinally&lt;br /&gt;
} L_009b: ret .try L_005d to L_008f finally handler L_008f to L_009b&lt;/pre&gt;
&lt;p&gt;
The text in red is my emphasis. So, the moral of this story, when you take control
of the data yourself, you MUST call dispose on the IEnumerable&amp;lt;T&amp;gt; object when
you are done with it.
&lt;/p&gt;
&lt;p&gt;
Enjoy!
&lt;/p&gt;</description>
      <comments>http://www.samuraiprogrammer.com/blog/CommentView,guid,6051d755-1879-46b5-8a5a-9b69b47d461d.aspx</comments>
      <category>Database</category>
      <category>Development</category>
      <category>LINQ</category>
      <category>Performance</category>
    </item>
    <item>
      <trackback:ping>http://www.samuraiprogrammer.com/blog/Trackback.aspx?guid=c5f858a6-286a-4b0b-8d78-a3be23d60d47</trackback:ping>
      <pingback:server>http://www.samuraiprogrammer.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.samuraiprogrammer.com/blog/PermaLink,guid,c5f858a6-286a-4b0b-8d78-a3be23d60d47.aspx</pingback:target>
      <dc:creator>Greg Varveris</dc:creator>
      <wfw:comment>http://www.samuraiprogrammer.com/blog/CommentView,guid,c5f858a6-286a-4b0b-8d78-a3be23d60d47.aspx</wfw:comment>
      <wfw:commentRss>http://www.samuraiprogrammer.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=c5f858a6-286a-4b0b-8d78-a3be23d60d47</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I was helping a co-worker today with one of his screens and realized that it may make
a useful little tutorial for all those other folks out there. This was somewhat interesting
because it follows up pretty well on my <a href="http://www.samuraiprogrammer.com/blog/2010/07/23/OnetoMaryWhatIsTheBestWayToStoreTheValues.aspx" target="_blank">previous
post</a> as I talk about saving records with a 1 to many relationship. Basically,
he needed to develop a screen similar to the following:
</p>
        <p>
          <a href="http://www.samuraiprogrammer.com/community/blogimages/GridViewGroupingandCheckboxLists_13FC4/image.png">
            <img style="display: block; float: none; margin-left: auto; margin-right: auto" border="0" alt="image" src="http://www.samuraiprogrammer.com/community/blogimages/GridViewGroupingandCheckboxLists_13FC4/image_thumb.png" width="213" height="193" />
          </a>
        </p>
        <p>
This is actually a pretty simple page, but there are a few places that might cause
a hiccup or two:
</p>
        <ul>
          <li>
Grouping items in a checkbox list. 
</li>
          <li>
Getting the value for each Attribute (ie: the PK of the Attribute itself)</li>
        </ul>
        <p>
For the first item - grouping inside of a checkbox list. This actually won't work
- there is no way to specify groups of checkboxes or additional properties to define
checkboxes or any of that...so, the only real option is to put the checkboxes into
a GridView control. Now, I've done this type of grouping many times previously and
it never really felt right. After Googling the problem with him - "grouping items
in a gridview" - the first result is a great series of classes posted <a href="http://www.agrinei.com/gridviewhelper/gridviewhelper_en.htm">here</a>.
The only problem with this method is that it is focused on grouping within reports.
The difference in this situation is that we wanted the checkboxes to maintain their
state between postbacks. If you perform a postback using the article's method, then
not only will your checkboxes lose their state (kinda sorta) but the Header row for
each group will disappear. 
</p>
        <p>
Then, I happened to recall something similar written by <a href="http://blogs.msdn.com/mattdotson">Matt
Dotson</a> and his use of cell-spanning to accomplish a similar feat. He has a great
blog entry posted <a href="http://blogs.msdn.com/mattdotson/articles/541795.aspx">here</a> to
illustrate the concept. In-fact, he also has a great CodePlex project <a href="http://www.codeplex.com/ASPNetRealWorldContr">here</a> that
has a bunch of useful "Real World" ASP.NET webcontrols in it. One of these
useful controls is a GroupingGridView. This is essentially a GridView to perform the
actual Grid Grouping. By default, using Matt's sample, the GridView renders like this:
</p>
        <p>
          <a href="http://www.samuraiprogrammer.com/community/blogimages/GridViewGroupingandCheckboxLists_13FC4/image_3.png">
            <img style="display: block; float: none; margin-left: auto; margin-right: auto" border="0" alt="image" src="http://www.samuraiprogrammer.com/community/blogimages/GridViewGroupingandCheckboxLists_13FC4/image_thumb_3.png" width="277" height="282" />
          </a>
        </p>
        <p>
And the XHTML to output this simple page is:
</p>
        <pre class="csharpcode">
          <span class="kwrd">&lt;</span>
          <span class="html">rwg:GroupingGridView</span>
          <span class="attr">ID</span>
          <span class="kwrd">="GroupGrid"</span>
          <span class="attr">DataSourceID</span>
          <span class="kwrd">="PubsDataSource"</span>
          <span class="attr">AutoGenerateColumns</span>
          <span class="kwrd">="False"</span>
          <span class="attr">GroupingDepth</span>
          <span class="kwrd">="2"</span>
          <span class="attr">DataKeyNames</span>
          <span class="kwrd">="au_id"</span>
          <span class="attr">runat</span>
          <span class="kwrd">="server"</span>
          <span class="kwrd">&gt;</span>
          <span class="kwrd">&lt;</span>
          <span class="html">Columns</span>
          <span class="kwrd">&gt;</span>
          <span class="kwrd">&lt;</span>
          <span class="html">asp:BoundField</span>
          <span class="attr">HeaderText</span>
          <span class="kwrd">="State"</span>
          <span class="attr">DataField</span>
          <span class="kwrd">="state"</span>
          <span class="kwrd">/&gt;</span>
          <span class="kwrd">&lt;</span>
          <span class="html">asp:BoundField</span>
          <span class="attr">HeaderText</span>
          <span class="kwrd">="City"</span>
          <span class="attr">DataField</span>
          <span class="kwrd">="city"</span>
          <span class="kwrd">/&gt;</span>
          <span class="kwrd">&lt;</span>
          <span class="html">asp:BoundField</span>
          <span class="attr">HeaderText</span>
          <span class="kwrd">="Last
Name"</span>
          <span class="attr">DataField</span>
          <span class="kwrd">="au_lname"</span>
          <span class="kwrd">/&gt;</span>
          <span class="kwrd">&lt;</span>
          <span class="html">asp:BoundField</span>
          <span class="attr">HeaderText</span>
          <span class="kwrd">="First
Name"</span>
          <span class="attr">DataField</span>
          <span class="kwrd">="au_fname"</span>
          <span class="kwrd">/&gt;</span>
          <span class="kwrd">&lt;</span>
          <span class="html">asp:BoundField</span>
          <span class="attr">HeaderText</span>
          <span class="kwrd">="Phone"</span>
          <span class="attr">DataField</span>
          <span class="kwrd">="phone"</span>
          <span class="kwrd">/&gt;</span>
          <span class="kwrd">&lt;</span>
          <span class="html">asp:BoundField</span>
          <span class="attr">HeaderText</span>
          <span class="kwrd">="Address"</span>
          <span class="attr">DataField</span>
          <span class="kwrd">="address"</span>
          <span class="kwrd">/&gt;</span>
          <span class="kwrd">&lt;</span>
          <span class="html">asp:BoundField</span>
          <span class="attr">HeaderText</span>
          <span class="kwrd">="Zip
Code"</span>
          <span class="attr">DataField</span>
          <span class="kwrd">="zip"</span>
          <span class="kwrd">/&gt;</span>
          <span class="kwrd">&lt;</span>
          <span class="html">asp:CheckBoxField</span>
          <span class="attr">HeaderText</span>
          <span class="kwrd">="Contract"</span>
          <span class="attr">DataField</span>
          <span class="kwrd">="contract"</span>
          <span class="kwrd">/&gt;</span>
          <span class="kwrd">&lt;/</span>
          <span class="html">Columns</span>
          <span class="kwrd">&gt;</span>
          <span class="kwrd">&lt;/</span>
          <span class="html">rwg:GroupingGridView</span>
          <span class="kwrd">&gt;</span>
        </pre>
        <style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
        <p>
Nice, clean and simple - and it gets us most of the way there. Instead of actually
displaying the grouped items in the center of the cell, though, we needed the Group
text to display at the top of the cell. This is a very simple change to his source
code (available on the CodePlex site). In fact, it's only 1 additional line of code
in his SpanCellsRecursive method (see the marked line below):
</p>
        <pre class="csharpcode">
          <span class="kwrd">private</span>
          <span class="kwrd">void</span> SpanCellsRecursive(<span class="kwrd">int</span> columnIndex, <span class="kwrd">int</span> startRowIndex, <span class="kwrd">int</span> endRowIndex)
{ <span class="kwrd">if</span> (columnIndex &gt;= <span class="kwrd">this</span>.GroupingDepth
|| columnIndex &gt;= <span class="kwrd">this</span>.Columns.Count ) <span class="kwrd">return</span>;
TableCell groupStartCell = <span class="kwrd">null</span>; <span class="kwrd">int</span> groupStartRowIndex
= startRowIndex; <span class="kwrd">for</span> (<span class="kwrd">int</span> i =
startRowIndex; i &lt; endRowIndex; i++) { TableCell currentCell = <span class="kwrd">this</span>.Rows.Cells[columnIndex]; <span class="kwrd">bool</span> isNewGroup
= (<span class="kwrd">null</span> == groupStartCell) || (0 != String.CompareOrdinal(currentCell.Text,
groupStartCell.Text)); currentCell.VerticalAlign = VerticalAlign.Top; <span class="kwrd">if</span> (isNewGroup)
{ <span class="kwrd">if</span> (<span class="kwrd">null</span> != groupStartCell)
{ SpanCellsRecursive(columnIndex + 1, groupStartRowIndex, i); } groupStartCell = currentCell;
groupStartCell.RowSpan = 1; groupStartRowIndex = i; } <span class="kwrd">else</span> {
currentCell.Visible = <span class="kwrd">false</span>; groupStartCell.RowSpan += 1;
} } SpanCellsRecursive(columnIndex + 1, groupStartRowIndex, endRowIndex); }</pre>
        <style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
        <p>
Now that gets us the Grouped items in a GridView for our pretty display. Just using
that wonderful GridView gets us a page that looks like this:
</p>
        <p>
          <a href="http://www.samuraiprogrammer.com/community/blogimages/GridViewGroupingandCheckboxLists_13FC4/image_4.png">
            <img style="display: block; float: none; margin-left: auto; margin-right: auto" border="0" alt="image" src="http://www.samuraiprogrammer.com/community/blogimages/GridViewGroupingandCheckboxLists_13FC4/image_thumb_4.png" width="99" height="191" />
          </a>
        </p>
        <p>
With only this small amount of code in the XHTML:
</p>
        <pre class="csharpcode">
          <span class="kwrd">&lt;</span>
          <span class="html">RWC:GroupingGridView</span>
          <span class="attr">runat</span>
          <span class="kwrd">="server"</span>
          <span class="attr">ID</span>
          <span class="kwrd">="GroupingGridView1"</span>
          <span class="attr">AutoGenerateColumns</span>
          <span class="kwrd">="False"</span>
          <span class="attr">GroupingDepth</span>
          <span class="kwrd">="1"</span>
          <span class="attr">ShowHeader</span>
          <span class="kwrd">="False"</span>
          <span class="kwrd">&gt;</span>
          <span class="kwrd">&lt;</span>
          <span class="html">Columns</span>
          <span class="kwrd">&gt;</span>
          <span class="kwrd">&lt;</span>
          <span class="html">asp:BoundField</span>
          <span class="attr">DataField</span>
          <span class="kwrd">="GroupName"</span>
          <span class="attr">ShowHeader</span>
          <span class="kwrd">="False"</span>
          <span class="kwrd">/&gt;</span>
          <span class="kwrd">&lt;</span>
          <span class="html">asp:TemplateField</span>
          <span class="kwrd">&gt;</span>
          <span class="kwrd">&lt;</span>
          <span class="html">ItemTemplate</span>
          <span class="kwrd">&gt;</span>
          <span class="kwrd">&lt;</span>
          <span class="html">asp:checkbox</span>
          <span class="attr">runat</span>
          <span class="kwrd">="server"</span>
          <span class="attr">id</span>
          <span class="kwrd">="checkbox1"</span>
          <span class="attr">Text</span>
          <span class="kwrd">='&lt;%#
Eval("AttributeName") %&gt;'</span>
          <span class="attr">Checked</span>='&amp;<span class="attr">lt</span>;%# <span class="attr">DirectCast</span>(<span class="attr">Eval</span>(<span class="kwrd">"ParentId"</span>),<span class="attr">Int32</span>) <span class="kwrd">&gt;</span> 0 <span class="asp">%&gt;</span>' <span class="kwrd">/&gt;</span><span class="kwrd">&lt;/</span><span class="html">ItemTemplate</span><span class="kwrd">&gt;</span><span class="kwrd">&lt;/</span><span class="html">asp:TemplateField</span><span class="kwrd">&gt;</span><span class="kwrd">&lt;/</span><span class="html">Columns</span><span class="kwrd">&gt;</span><span class="kwrd">&lt;/</span><span class="html">RWC:GroupingGridView</span><span class="kwrd">&gt;</span></pre>
        <p>
And then you just bind this grid behind the scenes:
</p>
        <pre class="csharpcode">
          <span class="kwrd">Protected</span>
          <span class="kwrd">Sub</span> Page_Load(<span class="kwrd">ByVal</span> sender <span class="kwrd">As</span><span class="kwrd">Object</span>,
_ <span class="kwrd">ByVal</span> e <span class="kwrd">As</span> System.EventArgs)
_ <span class="kwrd">Handles</span><span class="kwrd">Me</span>.Load <span class="kwrd">If</span><span class="kwrd">Not</span> IsPostBack <span class="kwrd">Then</span><span class="kwrd">Dim</span> attributeList <span class="kwrd">As</span> _
System.Collections.Generic.IList(Of Attribute) attributeList = <span class="kwrd">Me</span>.GetAttributes() <span class="kwrd">With</span><span class="kwrd">Me</span>.GroupingGridView1
.DataSource = attributeList .DataBind() <span class="kwrd">End</span><span class="kwrd">With</span><span class="kwrd">End</span><span class="kwrd">If</span><span class="kwrd">End</span> Sub</pre>
        <style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
        <p>
Now, from a look and feel perspective - we're just about done. But what about getting
the values out of the checkbox - so that we know:
</p>
        <ol>
          <li>
Whether the checkbox was selected. 
</li>
          <li>
What the value of the checkbox is - ie: the primary key of the Attribute object.</li>
        </ol>
        <p>
The checked property is relatively simple to get out of the page. In the Submit button's
event, you loop through the rows in the GridView and extract out the instance of the
Checkbox for each row and then check the "Checked" property of the checkbox
to determine if the checkbox is selected:
</p>
        <pre class="csharpcode">
          <span class="kwrd">For</span>
          <span class="kwrd">Each</span> row <span class="kwrd">As</span> GridViewRow <span class="kwrd">In</span><span class="kwrd">Me</span>.gvGrouping.Rows <span class="kwrd">If</span> row.RowType
= DataControlRowType.DataRow <span class="kwrd">Then</span><span class="kwrd">Dim</span> obj <span class="kwrd">As</span> CheckBox
= _ <span class="kwrd">TryCast</span>(row.FindControl(<span class="str">"chkbxPermissions"</span>),
_ CheckBox) <span class="kwrd">If</span> obj IsNot <span class="kwrd">Nothing</span><span class="kwrd">Then</span> Response.Write(<span class="kwrd">String</span>.Format(<span class="str">"Row
{0}: checked value is {1} &lt;br&gt;"</span>, _ row.RowIndex.ToString, obj.Checked.ToString)) <span class="kwrd">End</span><span class="kwrd">If</span><span class="kwrd">End</span><span class="kwrd">If</span> Next</pre>
        <style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
        <p>
Now this will write to the page the RowIndex and a value indicating whether the checkbox
was checked. This will not, though, give me the AttributeId for these checkboxes because
the ASP.NET 2.0 Checkbox Control does not have actually have a "Value" property
like it does in a CheckBoxList control. So, what do we do? Well, there are two solutions:
</p>
        <ol>
          <li>
Use the DataKeyNames property of the GridView to specify that the AttributeId is our
key for this GridView and then extract it from the row. 
</li>
          <li>
Create a new CheckBox control that will include a new property to hold the Checkbox's
Value.</li>
        </ol>
        <p>
Given the two options mentioned above - there are no real differences. The actual
size of the page is EXACTLY the same and the speed to access the GridView's DataKey
property versus a new property on a new CheckBox control is no different. I'm choosing
to go with the latter as I know of a few other situations where a control like this
might come in handy. 
</p>
        <p>
So, since it is not already there - let's create a new control that derives from the
existing CheckBox control. We'll call this new control a ValueCheckBox control and
add a new property:
</p>
        <pre class="csharpcode">
          <span class="kwrd">Namespace</span> WebControls <span class="kwrd">Public</span><span class="kwrd">Class</span> ValueCheckBox <span class="kwrd">Inherits</span> CheckBox <span class="kwrd">Public</span><span class="kwrd">Property</span> CheckboxValue() <span class="kwrd">As</span><span class="kwrd">String</span><span class="kwrd">Get</span><span class="kwrd">Return</span><span class="kwrd">DirectCast</span>(ViewState(<span class="str">"checkboxvalue"</span>), <span class="kwrd">String</span>) <span class="kwrd">End</span><span class="kwrd">Get</span><span class="kwrd">Set</span>(<span class="kwrd">ByVal</span> value <span class="kwrd">As</span><span class="kwrd">String</span>)
ViewState(<span class="str">"checkboxvalue"</span>) = value <span class="kwrd">End</span><span class="kwrd">Set</span><span class="kwrd">End</span><span class="kwrd">Property</span><span class="kwrd">End</span><span class="kwrd">Class</span><span class="kwrd">End</span><span class="kwrd">Namespace</span></pre>
        <p>
Then, we add the new Register tag to the top of our page:
</p>
        <pre class="csharpcode">
          <span class="asp">&lt;%@ Register TagPrefix="sp"
Namespace="WebControls" %&gt;</span>
        </pre>
        <style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
        <p>
And then slightly change our XHTML to include a reference to the new checkbox in our
GridView:
</p>
        <pre class="csharpcode">
          <span class="kwrd">&lt;</span>
          <span class="html">RWC:GroupingGridView</span>
          <span class="attr">runat</span>
          <span class="kwrd">="server"</span>
          <span class="attr">ID</span>
          <span class="kwrd">="gvGrouping"</span>
          <span class="attr">AutoGenerateColumns</span>
          <span class="kwrd">="False"</span>
          <span class="attr">GroupingDepth</span>
          <span class="kwrd">="1"</span>
          <span class="attr">ShowHeader</span>
          <span class="kwrd">="False"</span>
          <span class="kwrd">&gt;</span>
          <span class="kwrd">&lt;</span>
          <span class="html">Columns</span>
          <span class="kwrd">&gt;</span>
          <span class="kwrd">&lt;</span>
          <span class="html">asp:BoundField</span>
          <span class="attr">DataField</span>
          <span class="kwrd">="GroupName"</span>
          <span class="attr">ShowHeader</span>
          <span class="kwrd">="False"</span>
          <span class="kwrd">/&gt;</span>
          <span class="kwrd">&lt;</span>
          <span class="html">asp:TemplateField</span>
          <span class="kwrd">&gt;</span>
          <span class="kwrd">&lt;</span>
          <span class="html">ItemTemplate</span>
          <span class="kwrd">&gt;</span>
          <span class="kwrd">&lt;</span>
          <span class="html">sp:ValueCheckBox</span>
          <span class="attr">runat</span>
          <span class="kwrd">="server"</span>
          <span class="attr">ID</span>
          <span class="kwrd">="chkbxPermissions"</span>
          <span class="attr">Text</span>
          <span class="kwrd">='&lt;%#
Eval("AttributeName") %&gt;'</span>
          <span class="attr">Checked</span>='&amp;<span class="attr">lt</span>;%# <span class="attr">DirectCast</span>(<span class="attr">Eval</span>(<span class="kwrd">"ParentId"</span>),<span class="attr">Int32</span>) <span class="kwrd">&gt;</span> 0 <span class="asp">%&gt;</span>'
CheckboxValue='<span class="asp">&lt;%</span># Eval(<span class="str">"AttributeId"</span>) <span class="asp">%&gt;</span>' <span class="kwrd">/&gt;</span><span class="kwrd">&lt;/</span><span class="html">ItemTemplate</span><span class="kwrd">&gt;</span><span class="kwrd">&lt;/</span><span class="html">asp:TemplateField</span><span class="kwrd">&gt;</span><span class="kwrd">&lt;/</span><span class="html">Columns</span><span class="kwrd">&gt;</span><span class="kwrd">&lt;/</span><span class="html">RWC:GroupingGridView</span><span class="kwrd">&gt;</span></pre>
        <p>
Lastly, you tweak your submit button code-behind to get at the new control:
</p>
        <pre class="csharpcode">
          <span class="kwrd">For</span>
          <span class="kwrd">Each</span> row <span class="kwrd">As</span> GridViewRow <span class="kwrd">In</span><span class="kwrd">Me</span>.gvGrouping.Rows <span class="kwrd">If</span> row.RowType
= DataControlRowType.DataRow <span class="kwrd">Then</span><span class="kwrd">Dim</span> obj <span class="kwrd">As</span> WebControls.ValueCheckBox
= _ <span class="kwrd">TryCast</span>(row.FindControl(<span class="str">"chkbxPermissions"</span>),
_ WebControls.ValueCheckBox) <span class="kwrd">If</span> obj IsNot <span class="kwrd">Nothing</span><span class="kwrd">Then</span><span class="kwrd">Dim</span> checked <span class="kwrd">As</span><span class="kwrd">Boolean</span> =
obj.Checked <span class="kwrd">Dim</span> checkboxValue <span class="kwrd">As</span><span class="kwrd">String</span> =
obj.CheckboxValue <span class="kwrd">End</span><span class="kwrd">If</span><span class="kwrd">End</span><span class="kwrd">If</span> Next</pre>
        <p>
And now you're done. My previous post discusses the best way to store these values,
so I won't go into that level. 
</p>
        <p>
Enjoy! 
</p>
      </body>
      <title>ASP.NET GridView Grouping and Checkbox Lists</title>
      <guid isPermaLink="false">http://www.samuraiprogrammer.com/blog/PermaLink,guid,c5f858a6-286a-4b0b-8d78-a3be23d60d47.aspx</guid>
      <link>http://www.samuraiprogrammer.com/blog/2010/07/23/ASPNETGridViewGroupingAndCheckboxLists.aspx</link>
      <pubDate>Fri, 23 Jul 2010 05:52:47 GMT</pubDate>
      <description>&lt;p&gt;
I was helping a co-worker today with one of his screens and realized that it may make
a useful little tutorial for all those other folks out there. This was somewhat interesting
because it follows up pretty well on my &lt;a href="http://www.samuraiprogrammer.com/blog/2010/07/23/OnetoMaryWhatIsTheBestWayToStoreTheValues.aspx" target="_blank"&gt;previous
post&lt;/a&gt; as I talk about saving records with a 1 to many relationship. Basically,
he needed to develop a screen similar to the following:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.samuraiprogrammer.com/community/blogimages/GridViewGroupingandCheckboxLists_13FC4/image.png"&gt;&lt;img style="display: block; float: none; margin-left: auto; margin-right: auto" border="0" alt="image" src="http://www.samuraiprogrammer.com/community/blogimages/GridViewGroupingandCheckboxLists_13FC4/image_thumb.png" width="213" height="193" /&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
This is actually a pretty simple page, but there are a few places that might cause
a hiccup or two:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Grouping items in a checkbox list. 
&lt;/li&gt;
&lt;li&gt;
Getting the value for each Attribute (ie: the PK of the Attribute itself)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
For the first item - grouping inside of a checkbox list. This actually won't work
- there is no way to specify groups of checkboxes or additional properties to define
checkboxes or any of that...so, the only real option is to put the checkboxes into
a GridView control. Now, I've done this type of grouping many times previously and
it never really felt right. After Googling the problem with him - &amp;quot;grouping items
in a gridview&amp;quot; - the first result is a great series of classes posted &lt;a href="http://www.agrinei.com/gridviewhelper/gridviewhelper_en.htm"&gt;here&lt;/a&gt;.
The only problem with this method is that it is focused on grouping within reports.
The difference in this situation is that we wanted the checkboxes to maintain their
state between postbacks. If you perform a postback using the article's method, then
not only will your checkboxes lose their state (kinda sorta) but the Header row for
each group will disappear. 
&lt;/p&gt;
&lt;p&gt;
Then, I happened to recall something similar written by &lt;a href="http://blogs.msdn.com/mattdotson"&gt;Matt
Dotson&lt;/a&gt; and his use of cell-spanning to accomplish a similar feat. He has a great
blog entry posted &lt;a href="http://blogs.msdn.com/mattdotson/articles/541795.aspx"&gt;here&lt;/a&gt; to
illustrate the concept. In-fact, he also has a great CodePlex project &lt;a href="http://www.codeplex.com/ASPNetRealWorldContr"&gt;here&lt;/a&gt; that
has a bunch of useful &amp;quot;Real World&amp;quot; ASP.NET webcontrols in it. One of these
useful controls is a GroupingGridView. This is essentially a GridView to perform the
actual Grid Grouping. By default, using Matt's sample, the GridView renders like this:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.samuraiprogrammer.com/community/blogimages/GridViewGroupingandCheckboxLists_13FC4/image_3.png"&gt;&lt;img style="display: block; float: none; margin-left: auto; margin-right: auto" border="0" alt="image" src="http://www.samuraiprogrammer.com/community/blogimages/GridViewGroupingandCheckboxLists_13FC4/image_thumb_3.png" width="277" height="282" /&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
And the XHTML to output this simple page is:
&lt;/p&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;rwg:GroupingGridView&lt;/span&gt; &lt;span class="attr"&gt;ID&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;GroupGrid&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;DataSourceID&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;PubsDataSource&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;AutoGenerateColumns&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;False&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;GroupingDepth&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;2&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;DataKeyNames&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;au_id&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;runat&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;server&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Columns&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;asp:BoundField&lt;/span&gt; &lt;span class="attr"&gt;HeaderText&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;State&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;DataField&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;state&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;asp:BoundField&lt;/span&gt; &lt;span class="attr"&gt;HeaderText&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;City&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;DataField&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;city&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;asp:BoundField&lt;/span&gt; &lt;span class="attr"&gt;HeaderText&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Last
Name&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;DataField&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;au_lname&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;asp:BoundField&lt;/span&gt; &lt;span class="attr"&gt;HeaderText&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;First
Name&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;DataField&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;au_fname&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;asp:BoundField&lt;/span&gt; &lt;span class="attr"&gt;HeaderText&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Phone&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;DataField&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;phone&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;asp:BoundField&lt;/span&gt; &lt;span class="attr"&gt;HeaderText&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Address&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;DataField&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;address&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;asp:BoundField&lt;/span&gt; &lt;span class="attr"&gt;HeaderText&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Zip
Code&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;DataField&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;zip&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;asp:CheckBoxField&lt;/span&gt; &lt;span class="attr"&gt;HeaderText&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Contract&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;DataField&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;contract&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Columns&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;rwg:GroupingGridView&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;
&lt;p&gt;
Nice, clean and simple - and it gets us most of the way there. Instead of actually
displaying the grouped items in the center of the cell, though, we needed the Group
text to display at the top of the cell. This is a very simple change to his source
code (available on the CodePlex site). In fact, it's only 1 additional line of code
in his SpanCellsRecursive method (see the marked line below):
&lt;/p&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; SpanCellsRecursive(&lt;span class="kwrd"&gt;int&lt;/span&gt; columnIndex, &lt;span class="kwrd"&gt;int&lt;/span&gt; startRowIndex, &lt;span class="kwrd"&gt;int&lt;/span&gt; endRowIndex)
{ &lt;span class="kwrd"&gt;if&lt;/span&gt; (columnIndex &amp;gt;= &lt;span class="kwrd"&gt;this&lt;/span&gt;.GroupingDepth
|| columnIndex &amp;gt;= &lt;span class="kwrd"&gt;this&lt;/span&gt;.Columns.Count ) &lt;span class="kwrd"&gt;return&lt;/span&gt;;
TableCell groupStartCell = &lt;span class="kwrd"&gt;null&lt;/span&gt;; &lt;span class="kwrd"&gt;int&lt;/span&gt; groupStartRowIndex
= startRowIndex; &lt;span class="kwrd"&gt;for&lt;/span&gt; (&lt;span class="kwrd"&gt;int&lt;/span&gt; i =
startRowIndex; i &amp;lt; endRowIndex; i++) { TableCell currentCell = &lt;span class="kwrd"&gt;this&lt;/span&gt;.Rows.Cells[columnIndex]; &lt;span class="kwrd"&gt;bool&lt;/span&gt; isNewGroup
= (&lt;span class="kwrd"&gt;null&lt;/span&gt; == groupStartCell) || (0 != String.CompareOrdinal(currentCell.Text,
groupStartCell.Text)); currentCell.VerticalAlign = VerticalAlign.Top; &lt;span class="kwrd"&gt;if&lt;/span&gt; (isNewGroup)
{ &lt;span class="kwrd"&gt;if&lt;/span&gt; (&lt;span class="kwrd"&gt;null&lt;/span&gt; != groupStartCell)
{ SpanCellsRecursive(columnIndex + 1, groupStartRowIndex, i); } groupStartCell = currentCell;
groupStartCell.RowSpan = 1; groupStartRowIndex = i; } &lt;span class="kwrd"&gt;else&lt;/span&gt; {
currentCell.Visible = &lt;span class="kwrd"&gt;false&lt;/span&gt;; groupStartCell.RowSpan += 1;
} } SpanCellsRecursive(columnIndex + 1, groupStartRowIndex, endRowIndex); }&lt;/pre&gt;
&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;
&lt;p&gt;
Now that gets us the Grouped items in a GridView for our pretty display. Just using
that wonderful GridView gets us a page that looks like this:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.samuraiprogrammer.com/community/blogimages/GridViewGroupingandCheckboxLists_13FC4/image_4.png"&gt;&lt;img style="display: block; float: none; margin-left: auto; margin-right: auto" border="0" alt="image" src="http://www.samuraiprogrammer.com/community/blogimages/GridViewGroupingandCheckboxLists_13FC4/image_thumb_4.png" width="99" height="191" /&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
With only this small amount of code in the XHTML:
&lt;/p&gt;
&lt;pre class="csharpcode"&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;RWC:GroupingGridView&lt;/span&gt; &lt;span class="attr"&gt;runat&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;server&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;ID&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;GroupingGridView1&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;AutoGenerateColumns&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;False&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;GroupingDepth&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;1&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;ShowHeader&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;False&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Columns&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;asp:BoundField&lt;/span&gt; &lt;span class="attr"&gt;DataField&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;GroupName&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;ShowHeader&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;False&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;asp:TemplateField&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;ItemTemplate&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;asp:checkbox&lt;/span&gt; &lt;span class="attr"&gt;runat&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;server&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;id&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;checkbox1&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Text&lt;/span&gt;&lt;span class="kwrd"&gt;='&amp;lt;%#
Eval(&amp;quot;AttributeName&amp;quot;) %&amp;gt;'&lt;/span&gt; &lt;span class="attr"&gt;Checked&lt;/span&gt;='&amp;amp;&lt;span class="attr"&gt;lt&lt;/span&gt;;%# &lt;span class="attr"&gt;DirectCast&lt;/span&gt;(&lt;span class="attr"&gt;Eval&lt;/span&gt;(&lt;span class="kwrd"&gt;&amp;quot;ParentId&amp;quot;&lt;/span&gt;),&lt;span class="attr"&gt;Int32&lt;/span&gt;) &lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt; 0 &lt;span class="asp"&gt;%&amp;gt;&lt;/span&gt;' &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;ItemTemplate&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;asp:TemplateField&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Columns&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;RWC:GroupingGridView&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;
And then you just bind this grid behind the scenes:
&lt;/p&gt;
&lt;pre class="csharpcode"&gt;    &lt;span class="kwrd"&gt;Protected&lt;/span&gt; &lt;span class="kwrd"&gt;Sub&lt;/span&gt; Page_Load(&lt;span class="kwrd"&gt;ByVal&lt;/span&gt; sender &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;Object&lt;/span&gt;,
_ &lt;span class="kwrd"&gt;ByVal&lt;/span&gt; e &lt;span class="kwrd"&gt;As&lt;/span&gt; System.EventArgs)
_ &lt;span class="kwrd"&gt;Handles&lt;/span&gt; &lt;span class="kwrd"&gt;Me&lt;/span&gt;.Load &lt;span class="kwrd"&gt;If&lt;/span&gt; &lt;span class="kwrd"&gt;Not&lt;/span&gt; IsPostBack &lt;span class="kwrd"&gt;Then&lt;/span&gt; &lt;span class="kwrd"&gt;Dim&lt;/span&gt; attributeList &lt;span class="kwrd"&gt;As&lt;/span&gt; _
System.Collections.Generic.IList(Of Attribute) attributeList = &lt;span class="kwrd"&gt;Me&lt;/span&gt;.GetAttributes() &lt;span class="kwrd"&gt;With&lt;/span&gt; &lt;span class="kwrd"&gt;Me&lt;/span&gt;.GroupingGridView1
.DataSource = attributeList .DataBind() &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;With&lt;/span&gt; &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;If&lt;/span&gt; &lt;span class="kwrd"&gt;End&lt;/span&gt; Sub&lt;/pre&gt;
&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;
&lt;p&gt;
Now, from a look and feel perspective - we're just about done. But what about getting
the values out of the checkbox - so that we know:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
Whether the checkbox was selected. 
&lt;/li&gt;
&lt;li&gt;
What the value of the checkbox is - ie: the primary key of the Attribute object.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
The checked property is relatively simple to get out of the page. In the Submit button's
event, you loop through the rows in the GridView and extract out the instance of the
Checkbox for each row and then check the &amp;quot;Checked&amp;quot; property of the checkbox
to determine if the checkbox is selected:
&lt;/p&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;For&lt;/span&gt; &lt;span class="kwrd"&gt;Each&lt;/span&gt; row &lt;span class="kwrd"&gt;As&lt;/span&gt; GridViewRow &lt;span class="kwrd"&gt;In&lt;/span&gt; &lt;span class="kwrd"&gt;Me&lt;/span&gt;.gvGrouping.Rows &lt;span class="kwrd"&gt;If&lt;/span&gt; row.RowType
= DataControlRowType.DataRow &lt;span class="kwrd"&gt;Then&lt;/span&gt; &lt;span class="kwrd"&gt;Dim&lt;/span&gt; obj &lt;span class="kwrd"&gt;As&lt;/span&gt; CheckBox
= _ &lt;span class="kwrd"&gt;TryCast&lt;/span&gt;(row.FindControl(&lt;span class="str"&gt;&amp;quot;chkbxPermissions&amp;quot;&lt;/span&gt;),
_ CheckBox) &lt;span class="kwrd"&gt;If&lt;/span&gt; obj IsNot &lt;span class="kwrd"&gt;Nothing&lt;/span&gt; &lt;span class="kwrd"&gt;Then&lt;/span&gt; Response.Write(&lt;span class="kwrd"&gt;String&lt;/span&gt;.Format(&lt;span class="str"&gt;&amp;quot;Row
{0}: checked value is {1} &amp;lt;br&amp;gt;&amp;quot;&lt;/span&gt;, _ row.RowIndex.ToString, obj.Checked.ToString)) &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;If&lt;/span&gt; &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;If&lt;/span&gt; Next&lt;/pre&gt;
&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;
&lt;p&gt;
Now this will write to the page the RowIndex and a value indicating whether the checkbox
was checked. This will not, though, give me the AttributeId for these checkboxes because
the ASP.NET 2.0 Checkbox Control does not have actually have a &amp;quot;Value&amp;quot; property
like it does in a CheckBoxList control. So, what do we do? Well, there are two solutions:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
Use the DataKeyNames property of the GridView to specify that the AttributeId is our
key for this GridView and then extract it from the row. 
&lt;/li&gt;
&lt;li&gt;
Create a new CheckBox control that will include a new property to hold the Checkbox's
Value.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
Given the two options mentioned above - there are no real differences. The actual
size of the page is EXACTLY the same and the speed to access the GridView's DataKey
property versus a new property on a new CheckBox control is no different. I'm choosing
to go with the latter as I know of a few other situations where a control like this
might come in handy. 
&lt;/p&gt;
&lt;p&gt;
So, since it is not already there - let's create a new control that derives from the
existing CheckBox control. We'll call this new control a ValueCheckBox control and
add a new property:
&lt;/p&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;Namespace&lt;/span&gt; WebControls &lt;span class="kwrd"&gt;Public&lt;/span&gt; &lt;span class="kwrd"&gt;Class&lt;/span&gt; ValueCheckBox &lt;span class="kwrd"&gt;Inherits&lt;/span&gt; CheckBox &lt;span class="kwrd"&gt;Public&lt;/span&gt; &lt;span class="kwrd"&gt;Property&lt;/span&gt; CheckboxValue() &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;String&lt;/span&gt; &lt;span class="kwrd"&gt;Get&lt;/span&gt; &lt;span class="kwrd"&gt;Return&lt;/span&gt; &lt;span class="kwrd"&gt;DirectCast&lt;/span&gt;(ViewState(&lt;span class="str"&gt;&amp;quot;checkboxvalue&amp;quot;&lt;/span&gt;), &lt;span class="kwrd"&gt;String&lt;/span&gt;) &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;Get&lt;/span&gt; &lt;span class="kwrd"&gt;Set&lt;/span&gt;(&lt;span class="kwrd"&gt;ByVal&lt;/span&gt; value &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;String&lt;/span&gt;)
ViewState(&lt;span class="str"&gt;&amp;quot;checkboxvalue&amp;quot;&lt;/span&gt;) = value &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;Set&lt;/span&gt; &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;Property&lt;/span&gt; &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;Class&lt;/span&gt; &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;Namespace&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;
Then, we add the new Register tag to the top of our page:
&lt;/p&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="asp"&gt;&amp;lt;%@ Register TagPrefix=&amp;quot;sp&amp;quot;
Namespace=&amp;quot;WebControls&amp;quot; %&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;
&lt;p&gt;
And then slightly change our XHTML to include a reference to the new checkbox in our
GridView:
&lt;/p&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;RWC:GroupingGridView&lt;/span&gt; &lt;span class="attr"&gt;runat&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;server&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;ID&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;gvGrouping&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;AutoGenerateColumns&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;False&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;GroupingDepth&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;1&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;ShowHeader&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;False&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Columns&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;asp:BoundField&lt;/span&gt; &lt;span class="attr"&gt;DataField&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;GroupName&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;ShowHeader&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;False&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;asp:TemplateField&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;ItemTemplate&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;sp:ValueCheckBox&lt;/span&gt; &lt;span class="attr"&gt;runat&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;server&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;ID&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;chkbxPermissions&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Text&lt;/span&gt;&lt;span class="kwrd"&gt;='&amp;lt;%#
Eval(&amp;quot;AttributeName&amp;quot;) %&amp;gt;'&lt;/span&gt; &lt;span class="attr"&gt;Checked&lt;/span&gt;='&amp;amp;&lt;span class="attr"&gt;lt&lt;/span&gt;;%# &lt;span class="attr"&gt;DirectCast&lt;/span&gt;(&lt;span class="attr"&gt;Eval&lt;/span&gt;(&lt;span class="kwrd"&gt;&amp;quot;ParentId&amp;quot;&lt;/span&gt;),&lt;span class="attr"&gt;Int32&lt;/span&gt;) &lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt; 0 &lt;span class="asp"&gt;%&amp;gt;&lt;/span&gt;'
CheckboxValue='&lt;span class="asp"&gt;&amp;lt;%&lt;/span&gt;# Eval(&lt;span class="str"&gt;&amp;quot;AttributeId&amp;quot;&lt;/span&gt;) &lt;span class="asp"&gt;%&amp;gt;&lt;/span&gt;' &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;ItemTemplate&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;asp:TemplateField&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Columns&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;RWC:GroupingGridView&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;
Lastly, you tweak your submit button code-behind to get at the new control:
&lt;/p&gt;
&lt;pre class="csharpcode"&gt;        &lt;span class="kwrd"&gt;For&lt;/span&gt; &lt;span class="kwrd"&gt;Each&lt;/span&gt; row &lt;span class="kwrd"&gt;As&lt;/span&gt; GridViewRow &lt;span class="kwrd"&gt;In&lt;/span&gt; &lt;span class="kwrd"&gt;Me&lt;/span&gt;.gvGrouping.Rows &lt;span class="kwrd"&gt;If&lt;/span&gt; row.RowType
= DataControlRowType.DataRow &lt;span class="kwrd"&gt;Then&lt;/span&gt; &lt;span class="kwrd"&gt;Dim&lt;/span&gt; obj &lt;span class="kwrd"&gt;As&lt;/span&gt; WebControls.ValueCheckBox
= _ &lt;span class="kwrd"&gt;TryCast&lt;/span&gt;(row.FindControl(&lt;span class="str"&gt;&amp;quot;chkbxPermissions&amp;quot;&lt;/span&gt;),
_ WebControls.ValueCheckBox) &lt;span class="kwrd"&gt;If&lt;/span&gt; obj IsNot &lt;span class="kwrd"&gt;Nothing&lt;/span&gt; &lt;span class="kwrd"&gt;Then&lt;/span&gt; &lt;span class="kwrd"&gt;Dim&lt;/span&gt; checked &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;Boolean&lt;/span&gt; =
obj.Checked &lt;span class="kwrd"&gt;Dim&lt;/span&gt; checkboxValue &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;String&lt;/span&gt; =
obj.CheckboxValue &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;If&lt;/span&gt; &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;If&lt;/span&gt; Next&lt;/pre&gt;
&lt;p&gt;
And now you're done. My previous post discusses the best way to store these values,
so I won't go into that level. 
&lt;/p&gt;
&lt;p&gt;
Enjoy! 
&lt;/p&gt;</description>
      <comments>http://www.samuraiprogrammer.com/blog/CommentView,guid,c5f858a6-286a-4b0b-8d78-a3be23d60d47.aspx</comments>
      <category>ASP.NET</category>
      <category>Database</category>
      <category>Development</category>
    </item>
    <item>
      <trackback:ping>http://www.samuraiprogrammer.com/blog/Trackback.aspx?guid=88873edb-631c-4a66-a315-5ebdfbc5964c</trackback:ping>
      <pingback:server>http://www.samuraiprogrammer.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.samuraiprogrammer.com/blog/PermaLink,guid,88873edb-631c-4a66-a315-5ebdfbc5964c.aspx</pingback:target>
      <dc:creator>Greg Varveris</dc:creator>
      <wfw:comment>http://www.samuraiprogrammer.com/blog/CommentView,guid,88873edb-631c-4a66-a315-5ebdfbc5964c.aspx</wfw:comment>
      <wfw:commentRss>http://www.samuraiprogrammer.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=88873edb-631c-4a66-a315-5ebdfbc5964c</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
 
</p>
        <p>
If you've been a developer for any period of time, you have probably come across this
question. If you're given a one-to-many relationship in a table, what is the best
way to insert those values into a database. For example, let's say that you had a
Person table and an Attribute table. Each person can have more than one attribute
associated with them, hence the 1-to-Many relationship. Your database diagram is probably
something that looks like this:
</p>
        <p>
          <a href="http://www.samuraiprogrammer.com/community/blogimages/OnetoManyWhatisthebestwaytostorethevalue_A44E/bs_1_to_many_relationship.jpg">
            <img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" border="0" alt="bs_1_to_many_relationship" src="http://www.samuraiprogrammer.com/community/blogimages/OnetoManyWhatisthebestwaytostorethevalue_A44E/bs_1_to_many_relationship_thumb.jpg" width="233" height="205" />
          </a>
        </p>
        <p>
So, if given a Person and a list of Attributes for that person, what is the best way
to insert rows into the PersonAttributeXref table? Well, if this is the first time
that you've done something like this, you probably came up with something like this:
</p>
        <ol>
          <li>
Create a Stored Procedure that accepts a UserId and AttributeId value and then insert
one row into the PersonAttributeXref table. 
</li>
          <li>
For each Attribute selected, you simply loop through them and call out to that Stored
Procedure once for each item you would like to insert. 
</li>
        </ol>
        <p>
So what is wrong with this method? Not a whole lot if you are only inserting a few
(1 to 3) rows into the PersonAttributeXref table. However, when inserting more than
those few rows into the table, you will begin to notice a performance hit. Why? Well,
if you are using something like the <a href="http://www.codeplex.com/entlib">Enterprise
Library</a> to perform your inserts, your code probably looks a little something like
this:
</p>
        <p>
        </p>
        <pre class="csharpcode">
          <span class="kwrd">Public</span>
          <span class="kwrd">Sub</span> InsertAttribute(<span class="kwrd">ByVal</span> userId <span class="kwrd">As</span> Int32, <span class="kwrd">ByVal</span> attributeId <span class="kwrd">As</span> Int32) <span class="kwrd">Dim</span> db <span class="kwrd">As</span> Database
= DatabaseFactory.CreateDatabase() Using dbCommand <span class="kwrd">As</span> Common.DbCommand
= _ db.GetStoredProcCommand(<span class="str">"USP_BS_INSERT_PERSONATTRIBUTEXREF"</span>)
db.AddInParameter(dbCommand, <span class="str">"@UserId"</span>, DbType.Int32,
userId) db.AddInParameter(dbCommand, <span class="str">"@AttributeId"</span>,
DbType.Int32, attributeId) <span class="kwrd">Try</span> db.ExecuteNonQuery(dbCommand) <span class="kwrd">Catch</span> ex <span class="kwrd">As</span> SqlClient.SqlException <span class="rem">'//
Insert error handling here.</span><span class="kwrd">End</span><span class="kwrd">Try</span><span class="kwrd">End</span> Using <span class="kwrd">End</span> Sub</pre>
        <style type="text/css">

.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
        <p>
The problem with something like this is that each time you call out to this method,
a new connection is established with the database and the insert is then completed.
The act of establishing a connection out to the database is very expensive - even
using Connection Pools. In-fact, during some tests that I ran locally, if you are
calling out to this method 100 times - it will probably take you in excess of about <strong>937,500</strong> ticks
to complete the transaction. You also don't have the option of rolling back the rows
inserted if something fails.
</p>
        <p>
Well, chances are, you've probably noticed this issue and have tried to overcome it
a variety of ways. In-fact, the next thing that I've seen people try is to concatenate
the attributeId's into a delimited string and then pass that string to a single stored
procedure:
</p>
        <pre class="csharpcode">
          <span class="kwrd">Dim</span> attributeIdList <span class="kwrd">As</span><span class="kwrd">New</span> System.Text.StringBuilder() <span class="kwrd">For</span> i <span class="kwrd">As</span> Int32
= 1 <span class="kwrd">To</span> MAXINSERTS <span class="kwrd">If</span> attributeIdList.Length
&gt; 0 <span class="kwrd">Then</span> attributeIdList.Append(<span class="str">","</span>) <span class="kwrd">End</span><span class="kwrd">If</span> attributeIdList.Append(i.ToString)
Next</pre>
        <style type="text/css">

.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
        <p>
And then in the Stored Procedure, you perform the String parsing using a simple UDF
like that which you can find <a href="http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=50648">here</a> and
then you perform the insert there - all wrapped in a nice little transaction. If you
have done something like this successfully, you have probably seen transaction times
somewhere in the neighborhood of <strong>625,000</strong> ticks for 100 inserted rows.
Wow! That's a nice a performance boost, right? Yes, it is - however, I've always been
a firm believer that the SQL Server is no place to be concatenating and splitting
strings. Just because you can do it, doesn't mean it should be done. In-fact, I'd
argue that splitting strings and concatenating strings makes your procedure a lot
less supportable than performing similar actions in .Net code. 
</p>
        <p>
Faced with these two options, I'm likely to propose a third option. In .NET, though,
you have the option of using Transactions (feel free to look <a href="http://www.simple-talk.com/dotnet/.net-framework/.net-2.0-transaction-model/">here</a> or <a href="http://www.15seconds.com/Issue/040914.htm">here</a> or
even <a href="http://www.code-magazine.com/article.aspx?quickid=0605031">here</a> for
a description). Transactions in .NET work the same way as Transactions in SQL. Basically,
you wrap one or more operations in a Transaction and if all operations succeed, then
the transaction is committed; if one or more fail, then you Roll it back. In the context
of this example, though, how would it work? Well, assuming you have an array of AttributeId's,
your code would probably look like this:
</p>
        <pre class="csharpcode">
          <span class="kwrd">Public</span>
          <span class="kwrd">Sub</span> InsertAttributeWithTransaction(<span class="kwrd">ByVal</span> userId <span class="kwrd">As</span> Int32,
_ <span class="kwrd">ByVal</span> attributeIdList <span class="kwrd">As</span> Int32()) <span class="kwrd">Dim</span> db <span class="kwrd">As</span> Database
= DatabaseFactory.CreateDatabase() Using dbCommand <span class="kwrd">As</span> Common.DbCommand
= _ db.GetStoredProcCommand(<span class="str">"USP_BS_INSERT_PERSONATTRIBUTEXREF"</span>)
db.AddInParameter(dbCommand, <span class="str">"@UserId"</span>, DbType.Int32,
userId) db.AddInParameter(dbCommand, <span class="str">"@AttributeId"</span>,
DbType.Int32, -1) Using connection <span class="kwrd">As</span> Common.DbConnection
= _ db.CreateConnection() connection.Open() <span class="kwrd">Dim</span> transaction <span class="kwrd">As</span> Common.DbTransaction
= _ connection.BeginTransaction() <span class="kwrd">Try</span><span class="kwrd">For</span> i <span class="kwrd">As</span> Int32
= 0 <span class="kwrd">To</span> attributeIdList.Length - 1 dbCommand.Parameters(<span class="str">"@AttributeId"</span>).Value
= _ attributeIdList(i) db.ExecuteNonQuery(dbCommand, transaction) <span class="kwrd">Next</span><span class="rem">'
Commit the transaction</span> transaction.Commit() <span class="kwrd">Catch</span> ex <span class="kwrd">As</span> Exception <span class="rem">'
Rollback transaction </span> transaction.Rollback() <span class="kwrd">End</span><span class="kwrd">Try</span> connection.Close() <span class="kwrd">End</span> Using <span class="kwrd">End</span> Using <span class="kwrd">End</span> Sub</pre>
        <style type="text/css">

.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
        <p>
As you can see, this is pretty nice and straight-forward. You instantiate the connection,
create the transaction, process the inserts and then depending upon the result of
the operations, you either Commit() or Rollback() the transaction. So, what is the
benefit of this? Well, aside from the obvious readability (and consequently supportability)
improvements - you also get a speed improvement too! In-fact, for the same 100 rows
that I inserted previously using the first or second approach, the total time to complete
the transaction here is between <strong>156,250 ticks and 312,500</strong> ticks.
That compared with with the 937,500 ticks in option 1 and 625,000 ticks in Option
2 - represents an incredible speed improvement - and that's only for 100 rows. Which,
I'd imagine, is the high-end in UI defined cases.
</p>
        <p>
If anyone has experienced issues with using .NET transactions or performance foibles,
I'd love to hear about them. Please feel free to either comment here or e-mail me
at greg at samurai programmer dot com.
</p>
      </body>
      <title>One-to-Many: What is the best way to store the values?</title>
      <guid isPermaLink="false">http://www.samuraiprogrammer.com/blog/PermaLink,guid,88873edb-631c-4a66-a315-5ebdfbc5964c.aspx</guid>
      <link>http://www.samuraiprogrammer.com/blog/2010/07/23/OnetoManyWhatIsTheBestWayToStoreTheValues.aspx</link>
      <pubDate>Fri, 23 Jul 2010 05:43:03 GMT</pubDate>
      <description>&lt;p&gt;
&amp;#160;
&lt;/p&gt;
&lt;p&gt;
If you've been a developer for any period of time, you have probably come across this
question. If you're given a one-to-many relationship in a table, what is the best
way to insert those values into a database. For example, let's say that you had a
Person table and an Attribute table. Each person can have more than one attribute
associated with them, hence the 1-to-Many relationship. Your database diagram is probably
something that looks like this:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.samuraiprogrammer.com/community/blogimages/OnetoManyWhatisthebestwaytostorethevalue_A44E/bs_1_to_many_relationship.jpg"&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" border="0" alt="bs_1_to_many_relationship" src="http://www.samuraiprogrammer.com/community/blogimages/OnetoManyWhatisthebestwaytostorethevalue_A44E/bs_1_to_many_relationship_thumb.jpg" width="233" height="205" /&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
So, if given a Person and a list of Attributes for that person, what is the best way
to insert rows into the PersonAttributeXref table? Well, if this is the first time
that you've done something like this, you probably came up with something like this:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
Create a Stored Procedure that accepts a UserId and AttributeId value and then insert
one row into the PersonAttributeXref table. 
&lt;/li&gt;
&lt;li&gt;
For each Attribute selected, you simply loop through them and call out to that Stored
Procedure once for each item you would like to insert. 
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
So what is wrong with this method? Not a whole lot if you are only inserting a few
(1 to 3) rows into the PersonAttributeXref table. However, when inserting more than
those few rows into the table, you will begin to notice a performance hit. Why? Well,
if you are using something like the &lt;a href="http://www.codeplex.com/entlib"&gt;Enterprise
Library&lt;/a&gt; to perform your inserts, your code probably looks a little something like
this:
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;Public&lt;/span&gt; &lt;span class="kwrd"&gt;Sub&lt;/span&gt; InsertAttribute(&lt;span class="kwrd"&gt;ByVal&lt;/span&gt; userId &lt;span class="kwrd"&gt;As&lt;/span&gt; Int32, &lt;span class="kwrd"&gt;ByVal&lt;/span&gt; attributeId &lt;span class="kwrd"&gt;As&lt;/span&gt; Int32) &lt;span class="kwrd"&gt;Dim&lt;/span&gt; db &lt;span class="kwrd"&gt;As&lt;/span&gt; Database
= DatabaseFactory.CreateDatabase() Using dbCommand &lt;span class="kwrd"&gt;As&lt;/span&gt; Common.DbCommand
= _ db.GetStoredProcCommand(&lt;span class="str"&gt;&amp;quot;USP_BS_INSERT_PERSONATTRIBUTEXREF&amp;quot;&lt;/span&gt;)
db.AddInParameter(dbCommand, &lt;span class="str"&gt;&amp;quot;@UserId&amp;quot;&lt;/span&gt;, DbType.Int32,
userId) db.AddInParameter(dbCommand, &lt;span class="str"&gt;&amp;quot;@AttributeId&amp;quot;&lt;/span&gt;,
DbType.Int32, attributeId) &lt;span class="kwrd"&gt;Try&lt;/span&gt; db.ExecuteNonQuery(dbCommand) &lt;span class="kwrd"&gt;Catch&lt;/span&gt; ex &lt;span class="kwrd"&gt;As&lt;/span&gt; SqlClient.SqlException &lt;span class="rem"&gt;'//
Insert error handling here.&lt;/span&gt; &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;Try&lt;/span&gt; &lt;span class="kwrd"&gt;End&lt;/span&gt; Using &lt;span class="kwrd"&gt;End&lt;/span&gt; Sub&lt;/pre&gt;
&lt;style type="text/css"&gt;

.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;
&lt;p&gt;
The problem with something like this is that each time you call out to this method,
a new connection is established with the database and the insert is then completed.
The act of establishing a connection out to the database is very expensive - even
using Connection Pools. In-fact, during some tests that I ran locally, if you are
calling out to this method 100 times - it will probably take you in excess of about &lt;strong&gt;937,500&lt;/strong&gt; ticks
to complete the transaction. You also don't have the option of rolling back the rows
inserted if something fails.
&lt;/p&gt;
&lt;p&gt;
Well, chances are, you've probably noticed this issue and have tried to overcome it
a variety of ways. In-fact, the next thing that I've seen people try is to concatenate
the attributeId's into a delimited string and then pass that string to a single stored
procedure:
&lt;/p&gt;
&lt;pre class="csharpcode"&gt;        &lt;span class="kwrd"&gt;Dim&lt;/span&gt; attributeIdList &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;New&lt;/span&gt; System.Text.StringBuilder() &lt;span class="kwrd"&gt;For&lt;/span&gt; i &lt;span class="kwrd"&gt;As&lt;/span&gt; Int32
= 1 &lt;span class="kwrd"&gt;To&lt;/span&gt; MAXINSERTS &lt;span class="kwrd"&gt;If&lt;/span&gt; attributeIdList.Length
&amp;gt; 0 &lt;span class="kwrd"&gt;Then&lt;/span&gt; attributeIdList.Append(&lt;span class="str"&gt;&amp;quot;,&amp;quot;&lt;/span&gt;) &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;If&lt;/span&gt; attributeIdList.Append(i.ToString)
Next&lt;/pre&gt;
&lt;style type="text/css"&gt;

.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;
&lt;p&gt;
And then in the Stored Procedure, you perform the String parsing using a simple UDF
like that which you can find &lt;a href="http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=50648"&gt;here&lt;/a&gt; and
then you perform the insert there - all wrapped in a nice little transaction. If you
have done something like this successfully, you have probably seen transaction times
somewhere in the neighborhood of &lt;strong&gt;625,000&lt;/strong&gt; ticks for 100 inserted rows.
Wow! That's a nice a performance boost, right? Yes, it is - however, I've always been
a firm believer that the SQL Server is no place to be concatenating and splitting
strings. Just because you can do it, doesn't mean it should be done. In-fact, I'd
argue that splitting strings and concatenating strings makes your procedure a lot
less supportable than performing similar actions in .Net code. 
&lt;/p&gt;
&lt;p&gt;
Faced with these two options, I'm likely to propose a third option. In .NET, though,
you have the option of using Transactions (feel free to look &lt;a href="http://www.simple-talk.com/dotnet/.net-framework/.net-2.0-transaction-model/"&gt;here&lt;/a&gt; or &lt;a href="http://www.15seconds.com/Issue/040914.htm"&gt;here&lt;/a&gt; or
even &lt;a href="http://www.code-magazine.com/article.aspx?quickid=0605031"&gt;here&lt;/a&gt; for
a description). Transactions in .NET work the same way as Transactions in SQL. Basically,
you wrap one or more operations in a Transaction and if all operations succeed, then
the transaction is committed; if one or more fail, then you Roll it back. In the context
of this example, though, how would it work? Well, assuming you have an array of AttributeId's,
your code would probably look like this:
&lt;/p&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;Public&lt;/span&gt; &lt;span class="kwrd"&gt;Sub&lt;/span&gt; InsertAttributeWithTransaction(&lt;span class="kwrd"&gt;ByVal&lt;/span&gt; userId &lt;span class="kwrd"&gt;As&lt;/span&gt; Int32,
_ &lt;span class="kwrd"&gt;ByVal&lt;/span&gt; attributeIdList &lt;span class="kwrd"&gt;As&lt;/span&gt; Int32()) &lt;span class="kwrd"&gt;Dim&lt;/span&gt; db &lt;span class="kwrd"&gt;As&lt;/span&gt; Database
= DatabaseFactory.CreateDatabase() Using dbCommand &lt;span class="kwrd"&gt;As&lt;/span&gt; Common.DbCommand
= _ db.GetStoredProcCommand(&lt;span class="str"&gt;&amp;quot;USP_BS_INSERT_PERSONATTRIBUTEXREF&amp;quot;&lt;/span&gt;)
db.AddInParameter(dbCommand, &lt;span class="str"&gt;&amp;quot;@UserId&amp;quot;&lt;/span&gt;, DbType.Int32,
userId) db.AddInParameter(dbCommand, &lt;span class="str"&gt;&amp;quot;@AttributeId&amp;quot;&lt;/span&gt;,
DbType.Int32, -1) Using connection &lt;span class="kwrd"&gt;As&lt;/span&gt; Common.DbConnection
= _ db.CreateConnection() connection.Open() &lt;span class="kwrd"&gt;Dim&lt;/span&gt; transaction &lt;span class="kwrd"&gt;As&lt;/span&gt; Common.DbTransaction
= _ connection.BeginTransaction() &lt;span class="kwrd"&gt;Try&lt;/span&gt; &lt;span class="kwrd"&gt;For&lt;/span&gt; i &lt;span class="kwrd"&gt;As&lt;/span&gt; Int32
= 0 &lt;span class="kwrd"&gt;To&lt;/span&gt; attributeIdList.Length - 1 dbCommand.Parameters(&lt;span class="str"&gt;&amp;quot;@AttributeId&amp;quot;&lt;/span&gt;).Value
= _ attributeIdList(i) db.ExecuteNonQuery(dbCommand, transaction) &lt;span class="kwrd"&gt;Next&lt;/span&gt; &lt;span class="rem"&gt;'
Commit the transaction&lt;/span&gt; transaction.Commit() &lt;span class="kwrd"&gt;Catch&lt;/span&gt; ex &lt;span class="kwrd"&gt;As&lt;/span&gt; Exception &lt;span class="rem"&gt;'
Rollback transaction &lt;/span&gt; transaction.Rollback() &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;Try&lt;/span&gt; connection.Close() &lt;span class="kwrd"&gt;End&lt;/span&gt; Using &lt;span class="kwrd"&gt;End&lt;/span&gt; Using &lt;span class="kwrd"&gt;End&lt;/span&gt; Sub&lt;/pre&gt;
&lt;style type="text/css"&gt;

.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;
&lt;p&gt;
As you can see, this is pretty nice and straight-forward. You instantiate the connection,
create the transaction, process the inserts and then depending upon the result of
the operations, you either Commit() or Rollback() the transaction. So, what is the
benefit of this? Well, aside from the obvious readability (and consequently supportability)
improvements - you also get a speed improvement too! In-fact, for the same 100 rows
that I inserted previously using the first or second approach, the total time to complete
the transaction here is between &lt;strong&gt;156,250 ticks and 312,500&lt;/strong&gt; ticks.
That compared with with the 937,500 ticks in option 1 and 625,000 ticks in Option
2 - represents an incredible speed improvement - and that's only for 100 rows. Which,
I'd imagine, is the high-end in UI defined cases.
&lt;/p&gt;
&lt;p&gt;
If anyone has experienced issues with using .NET transactions or performance foibles,
I'd love to hear about them. Please feel free to either comment here or e-mail me
at greg at samurai programmer dot com.
&lt;/p&gt;</description>
      <comments>http://www.samuraiprogrammer.com/blog/CommentView,guid,88873edb-631c-4a66-a315-5ebdfbc5964c.aspx</comments>
      <category>Database</category>
      <category>Development</category>
    </item>
  </channel>
</rss>