<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.microsoft.co.il/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>.NET Geek : Performance</title><link>http://blogs.microsoft.co.il/blogs/kim/archive/tags/Performance/default.aspx</link><description>Tags: Performance</description><dc:language>en</dc:language><generator>CommunityServer 2007.1 (Build: 20917.1142)</generator><item><title>My Favorite SQL Server 2k8 Feature</title><link>http://blogs.microsoft.co.il/blogs/kim/archive/2009/10/22/my-favorite-sql-server-2k8-feature.aspx</link><pubDate>Fri, 23 Oct 2009 02:31:00 GMT</pubDate><guid isPermaLink="false">b5c4f5bc-c09b-4439-a595-91a98c1847df:429409</guid><dc:creator>Kim</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.microsoft.co.il/blogs/kim/rsscomments.aspx?PostID=429409</wfw:commentRss><comments>http://blogs.microsoft.co.il/blogs/kim/archive/2009/10/22/my-favorite-sql-server-2k8-feature.aspx#comments</comments><description>&lt;p&gt;Since I&amp;#39;m typing this on my new Eee 1101HA I&amp;#39;m going to keep it short. (I hate these mini keyboards)&lt;/p&gt;
&lt;p&gt;Keeping an eye on our production Sql Server box is an integral part of my daily routine. I would not categorize myself as a DBA as I don&amp;#39;t do much administrative work related to our databases. I&amp;#39;m dealing mainly with issues that are related to development and making sure our system runs efficiently. One of those tasks is to make sure that our database is properly indexed and maintaining&amp;nbsp;indexes&amp;nbsp;as the database grows. Anyone who has done any significant work against a database knows the importance of proper indexing and that proper indexing is a balancing act. &lt;br /&gt;Clustered, non clustered, covering, fill factors and page splits are just a tiny subset of the things that you have to keep on top of. &lt;/p&gt;
&lt;p&gt;My absolute favorite feature in Sql Server 2008 is &lt;strong&gt;filtered indexes&lt;/strong&gt;. In a nutshell you create an index with a filter which is used to determine what goes into the index and what not. &lt;br /&gt;Let&amp;#39;s say you have a table with some bit flags. The selectivity on these columns&amp;nbsp;might be&amp;nbsp;too low to be of any real use for even the smartest query analyzer and you&amp;#39;ll often see&amp;nbsp;scans when filtering on these bit flags. &lt;br /&gt;In some of our&amp;nbsp;tables we have bit flags where the vast majority of the records have&amp;nbsp;these bit flags set to false. In these scenarios filtered indexes just shine. After creating a filtered index on only the true values of the bit flag we had queries that would take minutes to execute drop to a few milliseconds. &lt;/p&gt;
&lt;p&gt;For more information and some important&amp;nbsp;issues related to maintaining filtered indexes,&amp;nbsp;you should check out the following excellent posts. &lt;br /&gt;&lt;a href="http://www.sqlskills.com/BLOGS/KIMBERLY/post/Filtered-indexes-and-filtered-stats-might-become-seriously-out-of-date.aspx"&gt;http://www.sqlskills.com/BLOGS/KIMBERLY/post/Filtered-indexes-and-filtered-stats-might-become-seriously-out-of-date.aspx&lt;/a&gt;&lt;br /&gt;&lt;a href="http://blogs.technet.com/josebda/archive/2009/03/17/indexing-best-practices-for-sql-server-2008.aspx"&gt;http://blogs.technet.com/josebda/archive/2009/03/17/indexing-best-practices-for-sql-server-2008.aspx&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;&lt;img src="http://blogs.microsoft.co.il/aggbug.aspx?PostID=429409" width="1" height="1"&gt;</description><category domain="http://blogs.microsoft.co.il/blogs/kim/archive/tags/Sql+Server/default.aspx">Sql Server</category><category domain="http://blogs.microsoft.co.il/blogs/kim/archive/tags/Performance/default.aspx">Performance</category><category domain="http://blogs.microsoft.co.il/blogs/kim/archive/tags/DEV/default.aspx">DEV</category></item><item><title>Importing Large Xml Files to SQL Server Using SqlBulkCopy</title><link>http://blogs.microsoft.co.il/blogs/kim/archive/2009/06/15/importing-large-xml-files-to-sql-server-using-sqlbulkcopy.aspx</link><pubDate>Mon, 15 Jun 2009 21:00:00 GMT</pubDate><guid isPermaLink="false">b5c4f5bc-c09b-4439-a595-91a98c1847df:338092</guid><dc:creator>Kim</dc:creator><slash:comments>23</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.microsoft.co.il/blogs/kim/rsscomments.aspx?PostID=338092</wfw:commentRss><comments>http://blogs.microsoft.co.il/blogs/kim/archive/2009/06/15/importing-large-xml-files-to-sql-server-using-sqlbulkcopy.aspx#comments</comments><description>&lt;p&gt;Say you have a large Xml file that contains relatively tabular data that you want to import into SQL Server. There are several ways to go about this. Let’s look at a couple of options. &lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Load the file into an XDocument. Extract elements from the DOM using Linq and then use ADO.Net to insert the data into the database. &lt;/li&gt;
&lt;li&gt;Load the data into a DataSet using ReadXml and save the data to the database &lt;/li&gt;
&lt;li&gt;Read through the data using an Xml reader and save each record to the database &lt;/li&gt;&lt;/ol&gt;
&lt;p&gt;Options number 1 and 2 requires that we load the entire document into memory before processing. We will work under the assumption that the files we receive are too large to load into memory. That leaves with option number 3 which allows us to read the file in a fast forward only mode where we only hold a small portion of the file in memory. Once an item has been processed and the reader moves forward, the previously read data is unavailable to the reader. The main bottleneck now is how do we push the data in a really efficient way into the database. First of all let’s look at some sample data.&lt;/p&gt;
&lt;div style="FONT-FAMILY:consolas;BACKGROUND:white;COLOR:black;FONT-SIZE:10pt;"&gt;
&lt;div style="FONT-FAMILY:consolas;BACKGROUND:white;COLOR:black;FONT-SIZE:10pt;"&gt;&lt;pre style="MARGIN:0px;"&gt;&lt;span style="COLOR:blue;"&gt;&amp;lt;?&lt;/span&gt;&lt;span style="COLOR:#a31515;"&gt;xml&lt;/span&gt;&lt;span style="COLOR:blue;"&gt; &lt;/span&gt;&lt;span style="COLOR:red;"&gt;version&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="COLOR:blue;"&gt;1.0&lt;/span&gt;&amp;quot;&lt;span style="COLOR:blue;"&gt; &lt;/span&gt;&lt;span style="COLOR:red;"&gt;encoding&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="COLOR:blue;"&gt;utf-8&lt;/span&gt;&amp;quot;&lt;span style="COLOR:blue;"&gt;?&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&lt;span style="COLOR:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR:#a31515;"&gt;lab_results&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&lt;span style="COLOR:blue;"&gt;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR:#a31515;"&gt;result&lt;/span&gt;&lt;span style="COLOR:blue;"&gt; &lt;/span&gt;&lt;span style="COLOR:red;"&gt;type&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="COLOR:blue;"&gt;A01&lt;/span&gt;&amp;quot;&lt;span style="COLOR:blue;"&gt; &lt;/span&gt;&lt;span style="COLOR:red;"&gt;origin&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="COLOR:blue;"&gt;xb102&lt;/span&gt;&amp;quot;&lt;span style="COLOR:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&lt;span style="COLOR:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR:#a31515;"&gt;name&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;&amp;gt;&lt;/span&gt;aaa&lt;span style="COLOR:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR:#a31515;"&gt;name&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&lt;span style="COLOR:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR:#a31515;"&gt;description&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;&amp;gt;&lt;/span&gt;sample description1&lt;span style="COLOR:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR:#a31515;"&gt;description&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&lt;span style="COLOR:blue;"&gt;&amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style="COLOR:#a31515;"&gt;result&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&lt;span style="COLOR:blue;"&gt;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR:#a31515;"&gt;result&lt;/span&gt;&lt;span style="COLOR:blue;"&gt; &lt;/span&gt;&lt;span style="COLOR:red;"&gt;type&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="COLOR:blue;"&gt;A02&lt;/span&gt;&amp;quot;&lt;span style="COLOR:blue;"&gt; &lt;/span&gt;&lt;span style="COLOR:red;"&gt;origin&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="COLOR:blue;"&gt;xb103&lt;/span&gt;&amp;quot;&lt;span style="COLOR:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&lt;span style="COLOR:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR:#a31515;"&gt;name&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;&amp;gt;&lt;/span&gt;bbb&lt;span style="COLOR:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR:#a31515;"&gt;name&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&lt;span style="COLOR:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR:#a31515;"&gt;description&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;&amp;gt;&lt;/span&gt;sample description2&lt;span style="COLOR:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR:#a31515;"&gt;description&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&lt;span style="COLOR:blue;"&gt;&amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style="COLOR:#a31515;"&gt;result&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&lt;span style="COLOR:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR:#a31515;"&gt;lab_results&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;&amp;gt;&lt;/span&gt;&amp;nbsp;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The files we are about to process contain lab results. Each file will contain somewhere between 5-8 million result elements. Each result element will contain approximately 150 characters. 150 characters * 2 (Unicode) * 5 million = about 1.5GB per file. Obviously we can’t read that into memory all at once. Another detail is that the file contains type and origin codes which needs to be mapped to their appropriate values in the database.&lt;/p&gt;
&lt;p&gt;Here’s the sample table structure that will have to hold the data we import.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.microsoft.co.il/blogs/kim/labresults_27D77EF5.jpg"&gt;&lt;img style="BORDER-RIGHT-WIDTH:0px;DISPLAY:inline;BORDER-TOP-WIDTH:0px;BORDER-BOTTOM-WIDTH:0px;BORDER-LEFT-WIDTH:0px;" title="lab results" border="0" alt="lab results" src="http://blogs.microsoft.co.il/blogs/kim/labresults_thumb_5AFE712F.jpg" width="669" height="287" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;LabResultOrigin and LabResultType are standard lookup tables. Here’s some sample data so we can conceptualize the conversions we will need to make later.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;LabResultType&lt;/strong&gt;&lt;/p&gt;
&lt;table cellspacing="0" cellpadding="2"&gt;

&lt;tr&gt;
&lt;td valign="top"&gt;TypeId&lt;/td&gt;
&lt;td valign="top"&gt;Description&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign="top"&gt;1&lt;/td&gt;
&lt;td valign="top"&gt;A01&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign="top"&gt;2&lt;/td&gt;
&lt;td valign="top"&gt;A02&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign="top"&gt;3&lt;/td&gt;
&lt;td valign="top"&gt;B01&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;LabResultOrigin&lt;/strong&gt;&lt;/p&gt;
&lt;table cellspacing="0" cellpadding="2"&gt;

&lt;tr&gt;
&lt;td valign="top"&gt;OriginId&lt;/td&gt;
&lt;td valign="top"&gt;Description&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign="top"&gt;1&lt;/td&gt;
&lt;td valign="top"&gt;xb102&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign="top"&gt;2&lt;/td&gt;
&lt;td valign="top"&gt;xb103&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign="top"&gt;3&lt;/td&gt;
&lt;td valign="top"&gt;xz101&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;p&gt;For example, when we process the Xml file we will need to convert the from the textual result type of “A01” to 1.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Importing the data&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;When importing using SqlBulkCopy there are two ways to feed it data. One is to use a DataTable which we discarded above because of the size of the files. Another option is to use a DataReader. The problem is that there is no class in .Net that reads xml and implements the IDataReader interface.&lt;/p&gt;
&lt;p&gt;That means we will have to roll our own. Looking at the IDataReader interface it seems we will have to implement a boatload of methods. Or do we? &lt;br /&gt;Here’s a neat little trick that was mentioned in the passing in a comment by “jezemine” in &lt;a href="http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=83181" target="_blank"&gt;this&lt;/a&gt; blog post. &lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Create a class that implements IDataReader. &lt;/li&gt;
&lt;li&gt;Press Alt+Shift+F10 to implement the interface members (with a throw NotImplementedException) &lt;/li&gt;
&lt;li&gt;Pass your class to SqlBulkCopy. It will break on a NotImplementedException of course. &lt;/li&gt;
&lt;li&gt;Go ahead and implement the method it crashed on. &lt;/li&gt;
&lt;li&gt;Repeat steps #3 and #4 until all required methods have been implemented.&lt;/li&gt;&lt;/ol&gt;
&lt;p&gt;Only 3 out of more than 20 methods in IDataReader are actually used by SqlBulkCopy. Not too bad.&lt;/p&gt;
&lt;p&gt;We will create an XmlDataReader class that implements IDataReader so that we can pass it to SqlBulkCopy. The calling code will look something like the following:&lt;/p&gt;
&lt;div style="FONT-FAMILY:consolas;BACKGROUND:white;COLOR:black;FONT-SIZE:10pt;"&gt;&lt;pre style="MARGIN:0px;"&gt;&lt;span style="COLOR:blue;"&gt;using&lt;/span&gt; (&lt;span style="COLOR:#2b91af;"&gt;XmlTextReader&lt;/span&gt; xmlTextReader = &lt;span style="COLOR:blue;"&gt;new&lt;/span&gt; &lt;span style="COLOR:#2b91af;"&gt;XmlTextReader&lt;/span&gt;(message.FileName))&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&lt;span style="COLOR:blue;"&gt;using&lt;/span&gt; (&lt;span style="COLOR:#2b91af;"&gt;SqlBulkCopy&lt;/span&gt; sqlBulkCopy = &lt;span style="COLOR:blue;"&gt;new&lt;/span&gt; &lt;span style="COLOR:#2b91af;"&gt;SqlBulkCopy&lt;/span&gt;(connectionString, &lt;span style="COLOR:#2b91af;"&gt;SqlBulkCopyOptions&lt;/span&gt;.TableLock))&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;{&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SetupBulkCopy(sqlBulkCopy);&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;var&lt;/span&gt; reader = &lt;span style="COLOR:blue;"&gt;new&lt;/span&gt; &lt;span style="COLOR:#2b91af;"&gt;LabResultDataReader&lt;/span&gt;(xmlTextReader);&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; sqlBulkCopy.WriteToServer(reader);&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;}&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;As you can see, there is no mention of an XmlDataReader, but rather a LabResultDataReader. I decided to split the reader into two distinct pieces. One is a general purpose XmlDataReader that can be used for other xml structures and not only the one in the sample. A special purpose LabResultDataReader is derived from XmlDataReader and this class knows how to handle the structure of the lab result xml file.&lt;/p&gt;
&lt;p&gt;In order to tell SqlBulkCopy how to map between the data in the file and the columns in the database we need some plumbing as seen in the call to SetupBulkCopy().&lt;/p&gt;
&lt;div style="FONT-FAMILY:consolas;BACKGROUND:white;COLOR:black;FONT-SIZE:10pt;"&gt;&lt;pre style="MARGIN:0px;"&gt;&lt;span style="COLOR:blue;"&gt;private&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;static&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;void&lt;/span&gt; SetupBulkCopy(&lt;span style="COLOR:#2b91af;"&gt;SqlBulkCopy&lt;/span&gt; sqlBulkCopy)&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;{&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; sqlBulkCopy.ColumnMappings.Add(&lt;span style="COLOR:blue;"&gt;new&lt;/span&gt; &lt;span style="COLOR:#2b91af;"&gt;SqlBulkCopyColumnMapping&lt;/span&gt;(0, &lt;span style="COLOR:#a31515;"&gt;&amp;quot;TypeId&amp;quot;&lt;/span&gt;));&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; sqlBulkCopy.ColumnMappings.Add(&lt;span style="COLOR:blue;"&gt;new&lt;/span&gt; &lt;span style="COLOR:#2b91af;"&gt;SqlBulkCopyColumnMapping&lt;/span&gt;(1, &lt;span style="COLOR:#a31515;"&gt;&amp;quot;OriginId&amp;quot;&lt;/span&gt;));&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; sqlBulkCopy.ColumnMappings.Add(&lt;span style="COLOR:blue;"&gt;new&lt;/span&gt; &lt;span style="COLOR:#2b91af;"&gt;SqlBulkCopyColumnMapping&lt;/span&gt;(2, &lt;span style="COLOR:#a31515;"&gt;&amp;quot;ResultName&amp;quot;&lt;/span&gt;));&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; sqlBulkCopy.ColumnMappings.Add(&lt;span style="COLOR:blue;"&gt;new&lt;/span&gt; &lt;span style="COLOR:#2b91af;"&gt;SqlBulkCopyColumnMapping&lt;/span&gt;(3, &lt;span style="COLOR:#a31515;"&gt;&amp;quot;Description&amp;quot;&lt;/span&gt;));&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; sqlBulkCopy.DestinationTableName = &lt;span style="COLOR:#a31515;"&gt;&amp;quot;LabResult&amp;quot;&lt;/span&gt;;&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;}&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Note that we didn’t include the LabResultId column in the mapping above. The reason for this is that the LabResultId is an Identity column and is generated automatically by SQL Server.&lt;/p&gt;
&lt;p&gt;The general purpose XmlDataReader is as follows:&lt;/p&gt;
&lt;div style="FONT-FAMILY:consolas;BACKGROUND:white;COLOR:black;FONT-SIZE:10pt;"&gt;&lt;pre style="MARGIN:0px;"&gt;&lt;span style="COLOR:blue;"&gt;public&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;abstract&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;class&lt;/span&gt; &lt;span style="COLOR:#2b91af;"&gt;XmlDataReader&lt;/span&gt; : &lt;span style="COLOR:#2b91af;"&gt;IDataReader&lt;/span&gt;&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;{&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;private&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;readonly&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;string&lt;/span&gt; m_rowElementName;&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;private&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;readonly&lt;/span&gt; &lt;span style="COLOR:#2b91af;"&gt;XmlReader&lt;/span&gt; m_xmlReader;&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;private&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;readonly&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;int&lt;/span&gt; m_fieldCount = -1;&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;private&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;bool&lt;/span&gt; m_disposed;&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;protected&lt;/span&gt; &lt;span style="COLOR:#2b91af;"&gt;IEnumerator&lt;/span&gt;&amp;lt;&lt;span style="COLOR:#2b91af;"&gt;XElement&lt;/span&gt;&amp;gt; m_enumerator;&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;public&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;abstract&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;object&lt;/span&gt; GetValue(&lt;span style="COLOR:blue;"&gt;int&lt;/span&gt; i);&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:gray;"&gt;///&lt;/span&gt;&lt;span style="COLOR:green;"&gt; &lt;/span&gt;&lt;span style="COLOR:gray;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:gray;"&gt;///&lt;/span&gt;&lt;span style="COLOR:green;"&gt; Initialize the XmlDataStreamer. After initialization call Read() to move the reader forward.&lt;/span&gt;&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:gray;"&gt;///&lt;/span&gt;&lt;span style="COLOR:green;"&gt; &lt;/span&gt;&lt;span style="COLOR:gray;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:gray;"&gt;///&lt;/span&gt;&lt;span style="COLOR:green;"&gt; &lt;/span&gt;&lt;span style="COLOR:gray;"&gt;&amp;lt;param name=&amp;quot;xmlReader&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="COLOR:green;"&gt;XmlReader used to iterate the data. Will be disposed by when done.&lt;/span&gt;&lt;span style="COLOR:gray;"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:gray;"&gt;///&lt;/span&gt;&lt;span style="COLOR:green;"&gt; &lt;/span&gt;&lt;span style="COLOR:gray;"&gt;&amp;lt;param name=&amp;quot;fieldCount&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="COLOR:green;"&gt;IDataReader FiledCount.&lt;/span&gt;&lt;span style="COLOR:gray;"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:gray;"&gt;///&lt;/span&gt;&lt;span style="COLOR:green;"&gt; &lt;/span&gt;&lt;span style="COLOR:gray;"&gt;&amp;lt;param name=&amp;quot;rowElementName&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="COLOR:green;"&gt;Name of the XML element that contains row data&lt;/span&gt;&lt;span style="COLOR:gray;"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;public&lt;/span&gt; XmlDataReader(&lt;span style="COLOR:#2b91af;"&gt;XmlReader&lt;/span&gt; xmlReader, &lt;span style="COLOR:blue;"&gt;int&lt;/span&gt; fieldCount, &lt;span style="COLOR:blue;"&gt;string&lt;/span&gt; rowElementName)&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; m_rowElementName = rowElementName;&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; m_fieldCount = fieldCount;&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; m_xmlReader = xmlReader;&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; m_enumerator = GetXmlStream().GetEnumerator();&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;public&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;bool&lt;/span&gt; Read()&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;return&lt;/span&gt; m_enumerator.MoveNext();&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;public&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;int&lt;/span&gt; FieldCount&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;get&lt;/span&gt; { &lt;span style="COLOR:blue;"&gt;return&lt;/span&gt; m_fieldCount; }&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;public&lt;/span&gt; &lt;span style="COLOR:#2b91af;"&gt;XElement&lt;/span&gt; CurrentElement&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;get&lt;/span&gt; { &lt;span style="COLOR:blue;"&gt;return&lt;/span&gt; m_enumerator.Current; }&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:gray;"&gt;///&lt;/span&gt;&lt;span style="COLOR:green;"&gt; &lt;/span&gt;&lt;span style="COLOR:gray;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:gray;"&gt;///&lt;/span&gt;&lt;span style="COLOR:green;"&gt; http://msdn.microsoft.com/en-us/library/system.xml.linq.xstreamingelement.aspx&lt;/span&gt;&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:gray;"&gt;///&lt;/span&gt;&lt;span style="COLOR:green;"&gt; &lt;/span&gt;&lt;span style="COLOR:gray;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:gray;"&gt;///&lt;/span&gt;&lt;span style="COLOR:green;"&gt; &lt;/span&gt;&lt;span style="COLOR:gray;"&gt;&amp;lt;param name=&amp;quot;m_xmlReader&amp;quot;&amp;gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:gray;"&gt;///&lt;/span&gt;&lt;span style="COLOR:green;"&gt; &lt;/span&gt;&lt;span style="COLOR:gray;"&gt;&amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;private&lt;/span&gt; &lt;span style="COLOR:#2b91af;"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="COLOR:#2b91af;"&gt;XElement&lt;/span&gt;&amp;gt; GetXmlStream()&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:#2b91af;"&gt;XElement&lt;/span&gt; rowElement;&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;using&lt;/span&gt; (m_xmlReader)&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; m_xmlReader.MoveToContent();&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;while&lt;/span&gt; (m_xmlReader.Read())&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;if&lt;/span&gt; (IsRowElement())&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; rowElement = &lt;span style="COLOR:#2b91af;"&gt;XElement&lt;/span&gt;.ReadFrom(m_xmlReader) &lt;span style="COLOR:blue;"&gt;as&lt;/span&gt; &lt;span style="COLOR:#2b91af;"&gt;XElement&lt;/span&gt;;&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;if&lt;/span&gt; (rowElement != &lt;span style="COLOR:blue;"&gt;null&lt;/span&gt;)&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;yield&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;return&lt;/span&gt; rowElement;&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;private&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;bool&lt;/span&gt; IsRowElement()&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;if&lt;/span&gt; (m_xmlReader.NodeType != &lt;span style="COLOR:#2b91af;"&gt;XmlNodeType&lt;/span&gt;.Element)&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;return&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;false&lt;/span&gt;;&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;return&lt;/span&gt; m_xmlReader.Name == m_rowElementName;&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;protected&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;virtual&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;void&lt;/span&gt; Dispose()&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;if&lt;/span&gt; (m_disposed)&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;return&lt;/span&gt;;&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; m_enumerator.Dispose();&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; m_disposed = &lt;span style="COLOR:blue;"&gt;true&lt;/span&gt;;&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&lt;span style="COLOR:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; #region&lt;/span&gt; Members not required by SqlBulkCopy&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&lt;span style="COLOR:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; #region&lt;/span&gt; IDataReader Members&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;public&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;bool&lt;/span&gt; NextResult()&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;throw&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;new&lt;/span&gt; &lt;span style="COLOR:#2b91af;"&gt;NotImplementedException&lt;/span&gt;();&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;public&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;int&lt;/span&gt; RecordsAffected&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;get&lt;/span&gt; { &lt;span style="COLOR:blue;"&gt;throw&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;new&lt;/span&gt; &lt;span style="COLOR:#2b91af;"&gt;NotImplementedException&lt;/span&gt;(); }&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;public&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;string&lt;/span&gt; GetDataTypeName(&lt;span style="COLOR:blue;"&gt;int&lt;/span&gt; i)&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;throw&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;new&lt;/span&gt; &lt;span style="COLOR:#2b91af;"&gt;NotImplementedException&lt;/span&gt;();&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;div style="FONT-FAMILY:consolas;BACKGROUND:white;COLOR:black;FONT-SIZE:10pt;"&gt;&lt;pre style="MARGIN:0px;"&gt;&lt;span style="COLOR:green;"&gt;    // Deleted tons of methods not required...&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;pre style="MARGIN:0px;"&gt;&lt;span style="COLOR:blue;"&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div style="FONT-FAMILY:consolas;BACKGROUND:white;COLOR:black;FONT-SIZE:10pt;"&gt;&lt;pre style="MARGIN:0px;"&gt;}&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now let’s have a look at the special purpose LabResult reader.&lt;/p&gt;
&lt;div style="FONT-FAMILY:consolas;BACKGROUND:white;COLOR:black;FONT-SIZE:10pt;"&gt;&lt;pre style="MARGIN:0px;"&gt;&lt;span style="COLOR:blue;"&gt;public&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;class&lt;/span&gt; &lt;span style="COLOR:#2b91af;"&gt;LabResultDataReader&lt;/span&gt; : &lt;span style="COLOR:#2b91af;"&gt;XmlDataReader&lt;/span&gt;&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;{&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;private&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;const&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;string&lt;/span&gt; XmlTagRow = &lt;span style="COLOR:#a31515;"&gt;&amp;quot;result&amp;quot;&lt;/span&gt;;&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;private&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;const&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;int&lt;/span&gt; FieldCount = 4;&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;private&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;const&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;int&lt;/span&gt; InvalidItemId = -1;&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;public&lt;/span&gt; LabResultDataReader(&lt;span style="COLOR:#2b91af;"&gt;XmlReader&lt;/span&gt; xmlReader)&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : &lt;span style="COLOR:blue;"&gt;base&lt;/span&gt;(xmlReader, FieldCount, XmlTagRow){ }&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;public&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;override&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;object&lt;/span&gt; GetValue(&lt;span style="COLOR:blue;"&gt;int&lt;/span&gt; i)&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;switch&lt;/span&gt; (i)&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;case&lt;/span&gt; 0:&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;return&lt;/span&gt; CurrentElement.Attribute(&lt;span style="COLOR:#a31515;"&gt;&amp;quot;type&amp;quot;&lt;/span&gt;).EnumFromValue&amp;lt;&lt;span style="COLOR:#2b91af;"&gt;ResultType&lt;/span&gt;&amp;gt;();&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;case&lt;/span&gt; 1:&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;return&lt;/span&gt; CurrentElement.Attribute(&lt;span style="COLOR:#a31515;"&gt;&amp;quot;origin&amp;quot;&lt;/span&gt;).EnumFromValue&amp;lt;&lt;span style="COLOR:#2b91af;"&gt;Origin&lt;/span&gt;&amp;gt;();&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;case&lt;/span&gt; 2:&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;return&lt;/span&gt; CurrentElement.Element(&lt;span style="COLOR:#a31515;"&gt;&amp;quot;name&amp;quot;&lt;/span&gt;).value;&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;case&lt;/span&gt; 3:&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;return&lt;/span&gt; CurrentElement.Element(&lt;span style="COLOR:#a31515;"&gt;&amp;quot;description&amp;quot;&lt;/span&gt;).value;&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;default&lt;/span&gt;:&lt;/pre&gt;
&lt;div style="FONT-FAMILY:consolas;BACKGROUND:white;COLOR:black;FONT-SIZE:10pt;"&gt;&lt;pre style="MARGIN:0px;"&gt;&lt;span style="COLOR:blue;"&gt;                throw&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;new&lt;/span&gt; &lt;span style="COLOR:#2b91af;"&gt;InvalidOperationException&lt;/span&gt;(&lt;span style="COLOR:#a31515;"&gt;&amp;quot;Column count mismatch.&amp;quot;&lt;/span&gt;);&lt;/pre&gt;&lt;/div&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;}&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;There are two main features of the XmlDataReader. The first is that it flattens the Xml hierarchical structure to resemble a row. For each iteration of the enumerator, it extracts the &amp;lt;result&amp;gt; element and all its children. The special purpose reader (in our example the LabResultsDataReader) maps the nested &amp;lt;result&amp;gt; tag to a set of column values. The second significant feature is the streaming nature of the reader. We never hold more than a single &amp;lt;result&amp;gt; element in memory at any given time.&lt;/p&gt;
&lt;p&gt;If you look at the code above and wondered what are those .EnumFromValue&amp;lt;&amp;gt; methods on the XmlAttributes, you were right. These are just Extension methods that I added for convenience.&lt;/p&gt;
&lt;div style="FONT-FAMILY:consolas;BACKGROUND:white;COLOR:black;FONT-SIZE:10pt;"&gt;&lt;pre style="MARGIN:0px;"&gt;&lt;span style="COLOR:blue;"&gt;public&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;static&lt;/span&gt; T EnumFromValue&amp;lt;T&amp;gt;(&lt;span style="COLOR:blue;"&gt;this&lt;/span&gt; &lt;span style="COLOR:#2b91af;"&gt;XAttribute&lt;/span&gt; attribute)&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;{&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;string&lt;/span&gt; value = attribute.Value;&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;if&lt;/span&gt; (&lt;span style="COLOR:blue;"&gt;string&lt;/span&gt;.IsNullOrEmpty(value))&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;return&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;default&lt;/span&gt;(T);&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;try&lt;/span&gt;&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; T converted = (T)&lt;span style="COLOR:#2b91af;"&gt;Enum&lt;/span&gt;.Parse(&lt;span style="COLOR:blue;"&gt;typeof&lt;/span&gt;(T), value, &lt;span style="COLOR:blue;"&gt;true&lt;/span&gt;);&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;return&lt;/span&gt; converted;&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;catch&lt;/span&gt; (&lt;span style="COLOR:#2b91af;"&gt;Exception&lt;/span&gt;)&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;return&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;default&lt;/span&gt;(T);&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;&lt;pre style="MARGIN:0px;"&gt;}&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;As you can see, despite that this turned into a not so short post, there’s not that much code required for this to work. Hopefully this will give you enough to assist you in building your own high performance ETL solution.&lt;/p&gt;
&lt;p&gt;A few drawbacks of the proposed solution. I have only had to process a very limited set of files. In the case where many files of different schema would have to be parsed and processed, the design of having a designated derived class for each type of file could become a pain point. There is no support for parsing files with a schema that is not known at compile time. This implies that if the schema changes or a new type of file needs to be imported, a new build is needed.&lt;/p&gt;
&lt;p&gt;Suggestions, comments, improvements etc. are welcome.&lt;/p&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fblogs.microsoft.co.il%2fblogs%2fkim%2farchive%2f2009%2f06%2f15%2fimporting-large-xml-files-to-sql-server-using-sqlbulkcopy.aspx"&gt;&lt;img border="0" alt="kick it on DotNetKicks.com" src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fblogs.microsoft.co.il%2fblogs%2fkim%2farchive%2f2009%2f06%2f15%2fimporting-large-xml-files-to-sql-server-using-sqlbulkcopy.aspx" /&gt;&lt;/a&gt;&lt;img src="http://blogs.microsoft.co.il/aggbug.aspx?PostID=338092" width="1" height="1"&gt;</description><category domain="http://blogs.microsoft.co.il/blogs/kim/archive/tags/Sql+Server/default.aspx">Sql Server</category><category domain="http://blogs.microsoft.co.il/blogs/kim/archive/tags/Performance/default.aspx">Performance</category><category domain="http://blogs.microsoft.co.il/blogs/kim/archive/tags/DEV/default.aspx">DEV</category><category domain="http://blogs.microsoft.co.il/blogs/kim/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.microsoft.co.il/blogs/kim/archive/tags/SqlBulkCopy/default.aspx">SqlBulkCopy</category></item><item><title>Hard Drive Speed and Visual Studio Performance</title><link>http://blogs.microsoft.co.il/blogs/kim/archive/2007/11/01/tip-trick-hard-drive-speed-and-visual-studio-performance.aspx</link><pubDate>Fri, 02 Nov 2007 02:22:00 GMT</pubDate><guid isPermaLink="false">b5c4f5bc-c09b-4439-a595-91a98c1847df:31353</guid><dc:creator>Kim</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.microsoft.co.il/blogs/kim/rsscomments.aspx?PostID=31353</wfw:commentRss><comments>http://blogs.microsoft.co.il/blogs/kim/archive/2007/11/01/tip-trick-hard-drive-speed-and-visual-studio-performance.aspx#comments</comments><description>&lt;p&gt;Scott Guthrie has just posted a &lt;a href="http://weblogs.asp.net/scottgu/archive/2007/11/01/tip-trick-hard-drive-speed-and-visual-studio-performance.aspx" target="_blank"&gt;post&lt;/a&gt; on how to increase the performance of Visual Studio. (The title of this post is actually his) He has posted several blog posts on how to improve the performance of Visual Studio &lt;a href="http://weblogs.asp.net/scottgu/archive/2006/09/22/Tip_2F00_Trick_3A00_-Optimizing-ASP.NET-2.0-Web-Project-Build-Performance-with-VS-2005.aspx" target="_blank"&gt;here&lt;/a&gt; and &lt;a href="http://weblogs.asp.net/scottgu/archive/2007/08/21/public-hotfix-patch-available-for-vs-2005-f5-debugging-performance-issue-with-asp-net.aspx" target="_blank"&gt;here&lt;/a&gt;. .NET tip of the day also has a couple of posts on VS performance &lt;a href="http://dotnettipoftheday.org/tips/speedup_visual_studio.aspx" target="_blank"&gt;here&lt;/a&gt; and &lt;a href="http://dotnettipoftheday.org/tips/optimize_launch_of_vs2005.aspx" target="_blank"&gt;here&lt;/a&gt;. In his &lt;a href="http://weblogs.asp.net/scottgu/archive/2007/11/01/tip-trick-hard-drive-speed-and-visual-studio-performance.aspx" target="_blank"&gt;latest post&lt;/a&gt; he points out the importance of the speed of the hard drive.&lt;/p&gt;
&lt;p&gt;Despite spending most of my time in Visual Studio I&amp;#39;ve had my fair share optimizing databases. When monitoring databases for perf problems you try to find which if any of the subsystems cause bottlenecks. Is the server CPU bound, disk bound etc.&lt;/p&gt;
&lt;p&gt;Turns out some skills transfer well to other environments. :-) I am doing my development on a notebook. (&lt;a href="http://blogs.microsoft.co.il/blogs/kim/archive/2006/12/07/Replacing-my-Thinkpad-_2D00_-Part-III.aspx" target="_blank"&gt;A hefty one&lt;/a&gt;. One that can compete if not outperform most desktops) Despite having a powerful machine it seemed to disk bound. eg. the hard drive subsystem is the main bottleneck and the other sub systems are under utilized waiting for IO completion. I was already running with a 100GB 7200 rpm Hitachi 2.5&amp;quot; drive and I wasn&amp;#39;t sure what I could do. I won&amp;#39;t upgrade this machine until late 2008 which is when I estimate the next substantial hardware upgrade will be available. After a short monitoring session my suspicion was confirmed. I&amp;#39;m wasting time waiting for IO. Since this is a notebook I can&amp;#39;t set up a RAID configuration or throw in a 10K rpm drive. &lt;/p&gt;
&lt;p&gt;A few months ago &lt;a href="http://www.pcconnection.com/ProductDetail?Sku=7760563" target="_blank"&gt;Hitachi released a new 200GB 7200 rpm disk&lt;/a&gt;. So what would that buy you you might ask. A lot! Hard drive performance isn&amp;#39;t only dependent on the platter rotation speed, but also on the density of the data on the platters. The denser (can you say that?) the data the more data is read/written per rotation.&lt;/p&gt;
&lt;p&gt;I ran out and got the 200GB version and I can just say that the performance increase is substantial. Hitachi claims close to 20% performance increase, but I haven&amp;#39;t done any benchmarks. My gut feeling is that it&amp;#39;s less, but that might be because of other factors as well.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;span class="sbmLink"&gt;
&lt;table class="" cellspacing="1" cellpadding="1"&gt;

&lt;tr&gt;
&lt;td class="sbmText" class="sbmText"&gt;Share this post : &lt;/td&gt;
&lt;td class="sbmDim" class="sbmDim"&gt;&lt;a class="sbmDim" title="Post it to digg" href="http://digg.com/submit?phase=2&amp;amp;url=http://blogs.microsoft.co.il/blogs/kim/archive/2007/11/01/tip-trick-hard-drive-speed-and-visual-studio-performance.aspx&amp;amp;title=Hard%20Drive%20Speed%20and%20Visual%20Studio%20Performance" target="_blank"&gt;&lt;img src="http://blogs.msdn.com/blogfiles/rahulso/WindowsLiveWriter/IconsfordifferentSocialBookmarkingSites_B387/digg14.png" border="0" alt="" /&gt;&lt;/a&gt; 
&lt;td class="sbmDim" class="sbmDim"&gt;&lt;a class="sbmDim" title="Post it to dotnetkicks" href="http://www.dotnetkicks.com/kick/?url=http://blogs.microsoft.co.il/blogs/kim/archive/2007/11/01/tip-trick-hard-drive-speed-and-visual-studio-performance.aspx&amp;amp;title=Hard%20Drive%20Speed%20and%20Visual%20Studio%20Performance" target="_blank"&gt;&lt;img src="http://blogs.msdn.com/blogfiles/rahulso/WindowsLiveWriter/IconsfordifferentSocialBookmarkingSites_B387/CropperCapture154.jpg" border="0" alt="" /&gt;&lt;/a&gt; 
&lt;td class="sbmDim" class="sbmDim"&gt;&lt;a class="sbmDim" title="Post it to reddit!" href="http://reddit.com/submit?url=http://blogs.microsoft.co.il/blogs/kim/archive/2007/11/01/tip-trick-hard-drive-speed-and-visual-studio-performance.aspx&amp;amp;title=Hard%20Drive%20Speed%20and%20Visual%20Studio%20Performance" target="_blank"&gt;&lt;img src="http://blogs.msdn.com/blogfiles/rahulso/WindowsLiveWriter/IconsfordifferentSocialBookmarkingSites_B387/reddit4.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/span&gt;&lt;img src="http://blogs.microsoft.co.il/aggbug.aspx?PostID=31353" width="1" height="1"&gt;</description><category domain="http://blogs.microsoft.co.il/blogs/kim/archive/tags/.NET/default.aspx">.NET</category><category domain="http://blogs.microsoft.co.il/blogs/kim/archive/tags/Visual+Studio/default.aspx">Visual Studio</category><category domain="http://blogs.microsoft.co.il/blogs/kim/archive/tags/Performance/default.aspx">Performance</category></item><item><title>Visual Studio "View Code" soo slow...</title><link>http://blogs.microsoft.co.il/blogs/kim/archive/2007/06/08/Visual-Studio-_2200_View-Code_2200_-soo-slow_2E002E002E00_.aspx</link><pubDate>Fri, 08 Jun 2007 04:00:00 GMT</pubDate><guid isPermaLink="false">b5c4f5bc-c09b-4439-a595-91a98c1847df:14278</guid><dc:creator>Kim</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.microsoft.co.il/blogs/kim/rsscomments.aspx?PostID=14278</wfw:commentRss><comments>http://blogs.microsoft.co.il/blogs/kim/archive/2007/06/08/Visual-Studio-_2200_View-Code_2200_-soo-slow_2E002E002E00_.aspx#comments</comments><description>&lt;P&gt;I don't know exactly why, but for some time, the first time I display a code window within Visual Studio there's intense disk activity for about 10 seconds. From that point on opening other source files is a snap.&lt;BR&gt;It's late so I'm going to make this a short one.&lt;/P&gt;
&lt;P&gt;Locating the problem:&lt;BR&gt;1) I fired up SysInternals&amp;nbsp;fileMon.&lt;BR&gt;2) set it to monitor only the C: drive&lt;BR&gt;3) turned off some disk intensive applications (&lt;A href="mailto:Folding@Home"&gt;Folding@Home&lt;/A&gt;, MSN Desktop search...)&lt;BR&gt;4) Created a new project in Visual Studio&lt;BR&gt;Stared at the fileMon log for about 30 seconds while Visual Studio was writing to the file:&lt;BR&gt;C:\Documents and Settings\kim\Local Settings\Application Data\Microsoft\VisualStudio\8.0\1033\ExpansionsXML.xml&lt;BR&gt;5) Googled for ExpansionsXML.xml&lt;/P&gt;
&lt;P&gt;Turns out this is Visual Studio's cache for snippets. The size was about 800KB. I deleted the file and created a new project. Visual Studio created a new file, but&amp;nbsp;this time the size was 210KB. It still took close to 10 seconds to display the first source file. I deleted all the snippet templates from:&lt;BR&gt;C:\Program Files\Microsoft Visual Studio 8\VC#\Snippets\1033\*.*&lt;BR&gt;and&lt;BR&gt;C:\Program Files\Microsoft Visual Studio 8\VB\Snippets\1033\*.*&lt;/P&gt;
&lt;P&gt;Now opening a source file was &lt;SPAN style="FONT-SIZE:10pt;COLOR:black;FONT-FAMILY:Tahoma;mso-fareast-font-family:'Times New Roman';mso-fareast-language:EN-US;mso-ansi-language:EN-US;mso-bidi-language:HE;"&gt;instantaneous&lt;/SPAN&gt;! Not that I use snippets a lot (I'm using &lt;A href="http://www.devexpress.com/Products/NET/IDETools/CodeRush/Index.xml"&gt;CodeRush&lt;/A&gt;), but I still wanted the snippets to stay around so I restored the deleted snippets.&lt;/P&gt;
&lt;P&gt;At this point I took a step back since something was puzzling me. Why does Visual Studio need to recreate the snippet cache every time I open Visual Studio? I only have a small amount of custom snippets and I almost never update my snippets. &lt;BR&gt;How can I tell Visual Studio to stop caching the snippets if the cache is present?&lt;/P&gt;
&lt;P&gt;I made the ExpansionsXML.xml read-only and that was sign enough for Visual Studio to stay away from the file!!!&lt;BR&gt;I'm only smacking my head since this has been bugging me for a few days...&lt;/P&gt;&lt;img src="http://blogs.microsoft.co.il/aggbug.aspx?PostID=14278" width="1" height="1"&gt;</description><category domain="http://blogs.microsoft.co.il/blogs/kim/archive/tags/.NET/default.aspx">.NET</category><category domain="http://blogs.microsoft.co.il/blogs/kim/archive/tags/Visual+Studio/default.aspx">Visual Studio</category><category domain="http://blogs.microsoft.co.il/blogs/kim/archive/tags/Performance/default.aspx">Performance</category><category domain="http://blogs.microsoft.co.il/blogs/kim/archive/tags/Code+Editor/default.aspx">Code Editor</category><category domain="http://blogs.microsoft.co.il/blogs/kim/archive/tags/Snippets/default.aspx">Snippets</category></item></channel></rss>