<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/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>Richard Murillo on Software Development</title><link>http://blogs.msdn.com/rimuri/default.aspx</link><description /><dc:language>en</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>Building Performant Line of Business Applications with LINQ to SQL</title><link>http://blogs.msdn.com/rimuri/archive/2009/09/01/building-performant-line-of-business-applications-with-linq-to-sql.aspx</link><pubDate>Tue, 01 Sep 2009 21:45:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9885587</guid><dc:creator>Richard Murillo</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/rimuri/comments/9885587.aspx</comments><wfw:commentRss>http://blogs.msdn.com/rimuri/commentrss.aspx?PostID=9885587</wfw:commentRss><wfw:comment>http://blogs.msdn.com/rimuri/rsscomments.aspx?PostID=9885587</wfw:comment><description>&lt;H1&gt;The Scenario &lt;/H1&gt;
&lt;P&gt;Throughout the article, I will refer to the AdventureWorks database and use the following hypothetical customer scenarios: &lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Customer browses list of all products &lt;/LI&gt;
&lt;LI&gt;Customer checks status of order through web portal showing all previous orders; detail for first order shown &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Each step in the scenario requires different entities in different configurations; to keep explanations brief we will only use the Customer, SalesOrderHeader, SalesOrderDetail, and Product entities. The basis for which you tune is based on the business objects for each bullet of the scenario, starting with minimizing what data you really need. &lt;/P&gt;
&lt;H1&gt;Minimizing your Payload &lt;/H1&gt;
&lt;P&gt;The most straightforward way to accomplish item two of the scenario is to retrieve all orders for a given customer and display them in a table on the portal. The user clicks some header information (like the order identifier) and is taken to a detail page. Simple enough—the relationships of the entities and how the context traverses them is unchanged. The customer object is loaded, and when the page requests the order data for rendering, that data is also retrieved from the system. The fundamental issue involved here is we have to make two trips to the database to retrieve the entities: one for the customer, the other for their orders. How can this be made more efficient? &lt;/P&gt;
&lt;H2&gt;Data shaping with DataLoadOptions &lt;/H2&gt;
&lt;P&gt;The LINQ to SQL framework allows the developer to specify how eager or lazy the DataContext should be in loading related entities and materializing them. By default related entities (as specified in a 1:1 or 1:* relationship) are materialized "on demand", or lazily, when the property wrapping those entities is invoked. Conversely, a DataContext may also be configured to eagerly load related entities in an effort to reduce the amount of queries and data materialized for a given query (Microsoft Corporation, 2007) by loading all related when an entity is materialized and various configurations in between. &lt;/P&gt;
&lt;P&gt;There is no absolute rule for configuring the DataContext one way or another, but is rather a function of what the object for the data is. An example of the differing configurations is evident in the various scenarios above. In scenario one, the customer does not need to know anything about their previous orders while placing a new order. In scenario two, the customer needs their order header information, but not the details. In scenario three, we need to know the customer, the order header information, and the detail. &lt;/P&gt;
&lt;P&gt;The mechanism to control this is called DataLoadOptions and can be associated with a DataContext to control entity materialization aggressiveness. &lt;/P&gt;
&lt;H2&gt;Projections and change tracking &lt;/H2&gt;
&lt;P&gt;Additionally a projection could be made as a result of a series of joins to provide a flattened, read-only view of the data. Unlike Entities, which have identities and can be modified, projections cannot be persisted and are represented in denormalized views. &lt;/P&gt;
&lt;H1&gt;Comparing LINQ to SQL performance with ADO.NET &lt;/H1&gt;
&lt;P&gt;ADO.NET maintains only the transfer and fundamental materialization of CLR types to represent data and not classes representing the entities themselves. With less overhead the raw speed shows fairly impressive numbers at the cost of the development convenience. &lt;/P&gt;
&lt;DIV&gt;
&lt;TABLE style="BORDER-COLLAPSE: collapse" border=0&gt;
&lt;COLGROUP&gt;
&lt;COL style="WIDTH: 224px"&gt;
&lt;COL style="WIDTH: 70px"&gt;
&lt;COL style="WIDTH: 70px"&gt;
&lt;COL style="WIDTH: 73px"&gt;
&lt;COL style="WIDTH: 74px"&gt;
&lt;COL style="WIDTH: 77px"&gt;&lt;/COLGROUP&gt;
&lt;TBODY vAlign=top&gt;
&lt;TR style="HEIGHT: 20px"&gt;
&lt;TD style="BORDER-BOTTOM: #4f81bd 1pt solid; BORDER-RIGHT-STYLE: none; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-LEFT-STYLE: none; BORDER-TOP: #4f81bd 1pt solid"&gt;
&lt;P&gt;&lt;SPAN style="COLOR: black"&gt;Method&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-BOTTOM: #4f81bd 1pt solid; BORDER-RIGHT-STYLE: none; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-LEFT-STYLE: none; BORDER-TOP: #4f81bd 1pt solid"&gt;
&lt;P style="TEXT-ALIGN: center"&gt;&lt;SPAN style="COLOR: black"&gt;&lt;STRONG&gt;Median&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-BOTTOM: #4f81bd 1pt solid; BORDER-RIGHT-STYLE: none; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-LEFT-STYLE: none; BORDER-TOP: #4f81bd 1pt solid"&gt;
&lt;P style="TEXT-ALIGN: center"&gt;&lt;SPAN style="COLOR: black"&gt;&lt;STRONG&gt;Mean&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-BOTTOM: #4f81bd 1pt solid; BORDER-RIGHT-STYLE: none; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-LEFT-STYLE: none; BORDER-TOP: #4f81bd 1pt solid"&gt;
&lt;P style="TEXT-ALIGN: center"&gt;&lt;SPAN style="COLOR: black"&gt;Standard Deviation&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-BOTTOM: #4f81bd 1pt solid; BORDER-RIGHT-STYLE: none; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-LEFT-STYLE: none; BORDER-TOP: #4f81bd 1pt solid"&gt;
&lt;P style="TEXT-ALIGN: center"&gt;&lt;SPAN style="COLOR: black"&gt;Minimum&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-BOTTOM: #4f81bd 1pt solid; BORDER-RIGHT-STYLE: none; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-LEFT-STYLE: none; BORDER-TOP: #4f81bd 1pt solid"&gt;
&lt;P style="TEXT-ALIGN: center"&gt;&lt;SPAN style="COLOR: black"&gt;Maximum&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR style="BACKGROUND: #d3e0ef; HEIGHT: 20px"&gt;
&lt;TD style="BORDER-RIGHT-STYLE: none; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-LEFT-STYLE: none"&gt;
&lt;P&gt;&lt;SPAN style="COLOR: black"&gt;&lt;STRONG&gt;DLINQ: no change tracking/compiled/projection&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-RIGHT-STYLE: none; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-LEFT-STYLE: none"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: black"&gt;3407.861&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-RIGHT-STYLE: none; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-LEFT-STYLE: none"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: black"&gt;3387.762&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-RIGHT-STYLE: none; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-LEFT-STYLE: none"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: black"&gt;200.316&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-RIGHT-STYLE: none; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-LEFT-STYLE: none"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: black"&gt;3073.884&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-RIGHT-STYLE: none; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-LEFT-STYLE: none"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: black"&gt;3644.475&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR style="HEIGHT: 20px"&gt;
&lt;TD style="PADDING-LEFT: 7px; PADDING-RIGHT: 7px"&gt;
&lt;P&gt;&lt;SPAN style="COLOR: black"&gt;&lt;STRONG&gt;ADO.NET: DataReader &lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="PADDING-LEFT: 7px; PADDING-RIGHT: 7px"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: black"&gt;3461.938&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="PADDING-LEFT: 7px; PADDING-RIGHT: 7px"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: black"&gt;3543.22&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="PADDING-LEFT: 7px; PADDING-RIGHT: 7px"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: black"&gt;232.798&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="PADDING-LEFT: 7px; PADDING-RIGHT: 7px"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: black"&gt;3453.19&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="PADDING-LEFT: 7px; PADDING-RIGHT: 7px"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: black"&gt;4240.387&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR style="BACKGROUND: #d3e0ef; HEIGHT: 29px"&gt;
&lt;TD style="BORDER-RIGHT-STYLE: none; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-LEFT-STYLE: none"&gt;
&lt;P&gt;&lt;SPAN style="COLOR: black"&gt;&lt;STRONG&gt;DLINQ: no change tracking/compiled &lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-RIGHT-STYLE: none; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-LEFT-STYLE: none"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: black"&gt;4978.377&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-RIGHT-STYLE: none; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-LEFT-STYLE: none"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: black"&gt;5018.974&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-RIGHT-STYLE: none; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-LEFT-STYLE: none"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: black"&gt;130.961&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-RIGHT-STYLE: none; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-LEFT-STYLE: none"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: black"&gt;4949.884&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-RIGHT-STYLE: none; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-LEFT-STYLE: none"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: black"&gt;5407.276&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR style="HEIGHT: 20px"&gt;
&lt;TD style="PADDING-LEFT: 7px; PADDING-RIGHT: 7px"&gt;
&lt;P&gt;&lt;SPAN style="COLOR: black"&gt;&lt;STRONG&gt;DLINQ: no change tracking &lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="PADDING-LEFT: 7px; PADDING-RIGHT: 7px"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: black"&gt;4978.478&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="PADDING-LEFT: 7px; PADDING-RIGHT: 7px"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: black"&gt;5010.796&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="PADDING-LEFT: 7px; PADDING-RIGHT: 7px"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: black"&gt;100.207&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="PADDING-LEFT: 7px; PADDING-RIGHT: 7px"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: black"&gt;4940.606&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="PADDING-LEFT: 7px; PADDING-RIGHT: 7px"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: black"&gt;5296.035&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR style="BACKGROUND: #d3e0ef; HEIGHT: 20px"&gt;
&lt;TD style="BORDER-RIGHT-STYLE: none; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-LEFT-STYLE: none"&gt;
&lt;P&gt;&lt;SPAN style="COLOR: black"&gt;&lt;STRONG&gt;DLINQ &lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-RIGHT-STYLE: none; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-LEFT-STYLE: none"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: black"&gt;5381.326&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-RIGHT-STYLE: none; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-LEFT-STYLE: none"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: black"&gt;5398.57&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-RIGHT-STYLE: none; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-LEFT-STYLE: none"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: black"&gt;54.385&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-RIGHT-STYLE: none; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-LEFT-STYLE: none"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: black"&gt;5340.671&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-RIGHT-STYLE: none; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-LEFT-STYLE: none"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: black"&gt;5543.181&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR style="HEIGHT: 20px"&gt;
&lt;TD style="PADDING-LEFT: 7px; PADDING-RIGHT: 7px"&gt;
&lt;P&gt;&lt;SPAN style="COLOR: black"&gt;&lt;STRONG&gt;DLINQ: compiled &lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="PADDING-LEFT: 7px; PADDING-RIGHT: 7px"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: black"&gt;5396.588&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="PADDING-LEFT: 7px; PADDING-RIGHT: 7px"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: black"&gt;5462.503&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="PADDING-LEFT: 7px; PADDING-RIGHT: 7px"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: black"&gt;154.085&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="PADDING-LEFT: 7px; PADDING-RIGHT: 7px"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: black"&gt;5351.099&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="PADDING-LEFT: 7px; PADDING-RIGHT: 7px"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: black"&gt;5786.155&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR style="BACKGROUND: #d3e0ef; HEIGHT: 20px"&gt;
&lt;TD style="BORDER-BOTTOM: #4f81bd 1pt solid; BORDER-RIGHT-STYLE: none; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-LEFT-STYLE: none"&gt;
&lt;P&gt;&lt;SPAN style="COLOR: black"&gt;&lt;STRONG&gt;ADO.NET: DataSet &lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-BOTTOM: #4f81bd 1pt solid; BORDER-RIGHT-STYLE: none; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-LEFT-STYLE: none"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: black"&gt;6198.333&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-BOTTOM: #4f81bd 1pt solid; BORDER-RIGHT-STYLE: none; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-LEFT-STYLE: none"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: black"&gt;6276.153&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-BOTTOM: #4f81bd 1pt solid; BORDER-RIGHT-STYLE: none; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-LEFT-STYLE: none"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: black"&gt;162.064&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-BOTTOM: #4f81bd 1pt solid; BORDER-RIGHT-STYLE: none; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-LEFT-STYLE: none"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: black"&gt;6146.066&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-BOTTOM: #4f81bd 1pt solid; BORDER-RIGHT-STYLE: none; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-LEFT-STYLE: none"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: black"&gt;6604.432&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;/DIV&gt;
&lt;P&gt;&lt;SPAN style="COLOR: #4f81bd; FONT-SIZE: 9pt"&gt;&lt;STRONG&gt;Table 1 Scenario 1: read only list of products &lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;The table shows results for what we might expect, about 3.5 milliseconds to load the products from the database using an ADO.NET DataReader and about 6.2 milliseconds using an ADO.NET DataSet. The data also shows that while a simple one entity LINQ to SQL object graph does not perform better than an ADO.NET DataReader, a projection that bypasses the identity cache performs just as well. For comparison let us examine the code required to perform the action, one as the traditional ADO.NET DataReader, the other as the LINQ to SQL projection. &lt;/P&gt;
&lt;DIV&gt;
&lt;TABLE style="BORDER-COLLAPSE: collapse" border=0&gt;
&lt;COLGROUP&gt;
&lt;COL style="WIDTH: 638px"&gt;&lt;/COLGROUP&gt;
&lt;TBODY vAlign=top&gt;
&lt;TR&gt;
&lt;TD style="BORDER-BOTTOM: black 0.5pt solid; BORDER-LEFT: black 0.5pt solid; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-TOP: black 0.5pt solid; BORDER-RIGHT: black 0.5pt solid"&gt;
&lt;DIV id=codeSnippetWrapper&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: '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&gt;List&amp;lt;&lt;SPAN style="COLOR: #0000ff"&gt;object&lt;/SPAN&gt;[]&amp;gt; productValues = &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; List&amp;lt;&lt;SPAN style="COLOR: #0000ff"&gt;object&lt;/SPAN&gt;[]&amp;gt;(); &lt;BR&gt;&lt;SPAN style="COLOR: #0000ff"&gt;using&lt;/SPAN&gt;( var connection = &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; SqlConnection( LinqToSqlPerf.Properties.Settings.Default.AdventureWorksConnectionString ) ) &lt;BR&gt;{ &lt;BR&gt;    &lt;SPAN style="COLOR: #0000ff"&gt;using&lt;/SPAN&gt;( var command = &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; SqlCommand( &lt;SPAN style="COLOR: #006080"&gt;"SELECT [t0].[ProductID], [t0].[Name], &lt;BR&gt;            [t0].[ProductNumber], [t0].[MakeFlag], [t0].[FinishedGoodsFlag], [t0].[Color], &lt;BR&gt;            [t0].[SafetyStockLevel], [t0].[ReorderPoint], [t0].[StandardCost], &lt;BR&gt;            [t0].[ListPrice], [t0].[Size], [t0].[SizeUnitMeasureCode], &lt;BR&gt;            [t0].[WeightUnitMeasureCode], [t0].[Weight], [t0].[DaysToManufacture], &lt;BR&gt;            [t0].[ProductLine], [t0].[Class], [t0].[Style], [t0].[ProductSubcategoryID], &lt;BR&gt;            [t0].[ProductModelID], [t0].[SellStartDate], [t0].[SellEndDate], &lt;BR&gt;            [t0].[DiscontinuedDate], [t0].[rowguid], [t0].[ModifiedDate] FROM &lt;BR&gt;            [Production].[Product] AS [t0]"&lt;/SPAN&gt; ) ) &lt;BR&gt;    { &lt;BR&gt;        command.Connection = connection; &lt;BR&gt;        connection.Open(); &lt;BR&gt;&lt;BR&gt;        var dr = command.ExecuteReader( CommandBehavior.CloseConnection ); &lt;BR&gt;&lt;BR&gt;        &lt;SPAN style="COLOR: #0000ff"&gt;while&lt;/SPAN&gt;( dr.Read() ) &lt;BR&gt;        { &lt;BR&gt;&lt;BR&gt;            var productRowValues = &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;object&lt;/SPAN&gt;[ dr.FieldCount ]; &lt;BR&gt;            dr.GetValues( productRowValues ); &lt;BR&gt;            productValues.Add( productRowValues ); &lt;BR&gt;        } &lt;BR&gt;&lt;BR&gt;        connection.Close(); &lt;BR&gt;    } &lt;BR&gt;}&lt;/PRE&gt;&lt;BR&gt;&lt;/DIV&gt;&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;/DIV&gt;
&lt;P&gt;&lt;SPAN style="COLOR: #4f81bd; FONT-SIZE: 9pt"&gt;&lt;STRONG&gt;Figure 1 Scenario 1 product retrieval as ADO.NET DataReader &lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;The resulting implementation is 11 lines of code with an embedded TSQL statement. &lt;/P&gt;
&lt;DIV id=codeSnippetWrapper&gt;&lt;BR&gt;&lt;/DIV&gt;
&lt;DIV&gt;
&lt;TABLE style="BORDER-COLLAPSE: collapse" border=0&gt;
&lt;TBODY vAlign=top&gt;
&lt;TR&gt;
&lt;TD style="BORDER-BOTTOM: black 0.5pt solid; BORDER-LEFT: black 0.5pt solid; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-TOP: black 0.5pt solid; BORDER-RIGHT: black 0.5pt solid"&gt;
&lt;DIV id=codeSnippetWrapper&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: '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&gt;&lt;SPAN style="COLOR: #0000ff"&gt;using&lt;/SPAN&gt;( var context = &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; DataClasses1DataContext() ) &lt;BR&gt;{ &lt;BR&gt;    context.DeferredLoadingEnabled = &lt;SPAN style="COLOR: #0000ff"&gt;false&lt;/SPAN&gt;; &lt;BR&gt;    context.ObjectTrackingEnabled = &lt;SPAN style="COLOR: #0000ff"&gt;false&lt;/SPAN&gt;; &lt;BR&gt;&lt;BR&gt;    var productsProjection = from product &lt;SPAN style="COLOR: #0000ff"&gt;in&lt;/SPAN&gt; context.GetScaledDownProductsFast() &lt;BR&gt;    select &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; &lt;BR&gt;    { &lt;BR&gt;        ProductID = product.ProductID, &lt;BR&gt;        Name = product.Name, &lt;BR&gt;        Number = product.ProductNumber, &lt;BR&gt;        Color = product.Color, &lt;BR&gt;        ListPrice = product.ListPrice, &lt;BR&gt;        Size = product.Size, &lt;BR&gt;        Weight = product.Weight, &lt;BR&gt;        Style = product.Style &lt;BR&gt;    }; &lt;BR&gt;&lt;BR&gt;    var products = productsProjection.ToArray(); &lt;BR&gt;}&lt;/PRE&gt;&lt;BR&gt;&lt;/DIV&gt;
&lt;P&gt;&lt;SPAN style="FONT-FAMILY: courier new; FONT-SIZE: 8pt"&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;/DIV&gt;
&lt;P&gt;&lt;SPAN style="COLOR: #4f81bd; FONT-SIZE: 9pt"&gt;&lt;STRONG&gt;Figure 2 Scenario 1 product retrieval as LINQ to SQL projection &lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;The resulting implementation 5 lines of code without an embedded TSQL statement. &lt;/P&gt;
&lt;P&gt;For the second scenario, we require joins on all four tables and require read only views. &lt;/P&gt;
&lt;DIV&gt;
&lt;TABLE style="BORDER-COLLAPSE: collapse" border=0&gt;
&lt;COLGROUP&gt;
&lt;COL style="WIDTH: 211px"&gt;
&lt;COL style="WIDTH: 78px"&gt;
&lt;COL style="WIDTH: 72px"&gt;
&lt;COL style="WIDTH: 72px"&gt;
&lt;COL style="WIDTH: 78px"&gt;
&lt;COL style="WIDTH: 78px"&gt;&lt;/COLGROUP&gt;
&lt;TBODY vAlign=top&gt;
&lt;TR style="HEIGHT: 20px"&gt;
&lt;TD style="BORDER-BOTTOM: #4f81bd 1pt solid; BORDER-RIGHT-STYLE: none; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-LEFT-STYLE: none; BORDER-TOP: #4f81bd 1pt solid"&gt;
&lt;P&gt;&lt;SPAN style="COLOR: black"&gt;Method&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-BOTTOM: #4f81bd 1pt solid; BORDER-RIGHT-STYLE: none; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-LEFT-STYLE: none; BORDER-TOP: #4f81bd 1pt solid"&gt;
&lt;P style="TEXT-ALIGN: center"&gt;&lt;SPAN style="COLOR: black"&gt;&lt;STRONG&gt;Median&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-BOTTOM: #4f81bd 1pt solid; BORDER-RIGHT-STYLE: none; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-LEFT-STYLE: none; BORDER-TOP: #4f81bd 1pt solid"&gt;
&lt;P style="TEXT-ALIGN: center"&gt;&lt;SPAN style="COLOR: black"&gt;&lt;STRONG&gt;Mean&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-BOTTOM: #4f81bd 1pt solid; BORDER-RIGHT-STYLE: none; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-LEFT-STYLE: none; BORDER-TOP: #4f81bd 1pt solid"&gt;
&lt;P style="TEXT-ALIGN: center"&gt;&lt;SPAN style="COLOR: black"&gt;Standard Deviation&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-BOTTOM: #4f81bd 1pt solid; BORDER-RIGHT-STYLE: none; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-LEFT-STYLE: none; BORDER-TOP: #4f81bd 1pt solid"&gt;
&lt;P style="TEXT-ALIGN: center"&gt;&lt;SPAN style="COLOR: black"&gt;Minimum&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-BOTTOM: #4f81bd 1pt solid; BORDER-RIGHT-STYLE: none; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-LEFT-STYLE: none; BORDER-TOP: #4f81bd 1pt solid"&gt;
&lt;P style="TEXT-ALIGN: center"&gt;&lt;SPAN style="COLOR: black"&gt;Maximum&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR style="BACKGROUND: #d3e0ef; HEIGHT: 43px"&gt;
&lt;TD style="BORDER-RIGHT-STYLE: none; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-LEFT-STYLE: none"&gt;
&lt;P&gt;&lt;SPAN style="COLOR: black"&gt;&lt;STRONG&gt;DLINQ: data load options (details)/compiled&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-RIGHT-STYLE: none; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-LEFT-STYLE: none"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: black"&gt;1313.25&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-RIGHT-STYLE: none; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-LEFT-STYLE: none"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: black"&gt;1433.731&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-RIGHT-STYLE: none; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-LEFT-STYLE: none"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: black"&gt;255.303&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-RIGHT-STYLE: none; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-LEFT-STYLE: none"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: black"&gt;1285.668&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-RIGHT-STYLE: none; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-LEFT-STYLE: none"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: black"&gt;1975.581&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR style="HEIGHT: 40px"&gt;
&lt;TD style="PADDING-LEFT: 7px; PADDING-RIGHT: 7px"&gt;
&lt;P&gt;&lt;SPAN style="COLOR: gray"&gt;&lt;STRONG&gt;&lt;EM&gt;DLINQ: data load options (details)/no change tracking/compiled &lt;/EM&gt;&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="PADDING-LEFT: 7px; PADDING-RIGHT: 7px"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: gray"&gt;&lt;EM&gt;1362.623&lt;/EM&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="PADDING-LEFT: 7px; PADDING-RIGHT: 7px"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: gray"&gt;&lt;EM&gt;1405.075&lt;/EM&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="PADDING-LEFT: 7px; PADDING-RIGHT: 7px"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: gray"&gt;&lt;EM&gt;158.995&lt;/EM&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="PADDING-LEFT: 7px; PADDING-RIGHT: 7px"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: gray"&gt;&lt;EM&gt;1302.991&lt;/EM&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="PADDING-LEFT: 7px; PADDING-RIGHT: 7px"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: gray"&gt;&lt;EM&gt;1874.912&lt;/EM&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR style="BACKGROUND: #d3e0ef; HEIGHT: 40px"&gt;
&lt;TD style="BORDER-RIGHT-STYLE: none; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-LEFT-STYLE: none"&gt;
&lt;P&gt;&lt;SPAN style="COLOR: gray"&gt;&lt;STRONG&gt;&lt;EM&gt;DLINQ: data load options (details)/no change tracking/compiled/cache &lt;/EM&gt;&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-RIGHT-STYLE: none; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-LEFT-STYLE: none"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: gray"&gt;&lt;EM&gt;1554.027&lt;/EM&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-RIGHT-STYLE: none; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-LEFT-STYLE: none"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: gray"&gt;&lt;EM&gt;1659.795&lt;/EM&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-RIGHT-STYLE: none; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-LEFT-STYLE: none"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: gray"&gt;&lt;EM&gt;284.601&lt;/EM&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-RIGHT-STYLE: none; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-LEFT-STYLE: none"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: gray"&gt;&lt;EM&gt;1392.884&lt;/EM&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-RIGHT-STYLE: none; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-LEFT-STYLE: none"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: gray"&gt;&lt;EM&gt;2289.98&lt;/EM&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR style="HEIGHT: 23px"&gt;
&lt;TD style="PADDING-LEFT: 7px; PADDING-RIGHT: 7px"&gt;
&lt;P&gt;&lt;SPAN style="COLOR: gray"&gt;&lt;STRONG&gt;&lt;EM&gt;ADO.NET: DataReader &lt;/EM&gt;&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="PADDING-LEFT: 7px; PADDING-RIGHT: 7px"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: gray"&gt;&lt;EM&gt;1614.67&lt;/EM&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="PADDING-LEFT: 7px; PADDING-RIGHT: 7px"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: gray"&gt;&lt;EM&gt;1694.006&lt;/EM&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="PADDING-LEFT: 7px; PADDING-RIGHT: 7px"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: gray"&gt;&lt;EM&gt;319.316&lt;/EM&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="PADDING-LEFT: 7px; PADDING-RIGHT: 7px"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: gray"&gt;&lt;EM&gt;1379.959&lt;/EM&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="PADDING-LEFT: 7px; PADDING-RIGHT: 7px"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: gray"&gt;&lt;EM&gt;2373.989&lt;/EM&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR style="BACKGROUND: #d3e0ef; HEIGHT: 20px"&gt;
&lt;TD style="BORDER-RIGHT-STYLE: none; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-LEFT-STYLE: none"&gt;
&lt;P&gt;&lt;SPAN style="COLOR: gray"&gt;&lt;STRONG&gt;&lt;EM&gt;ADO.NET: DataSet &lt;/EM&gt;&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-RIGHT-STYLE: none; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-LEFT-STYLE: none"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: gray"&gt;&lt;EM&gt;1940.488&lt;/EM&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-RIGHT-STYLE: none; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-LEFT-STYLE: none"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: gray"&gt;&lt;EM&gt;2072.922&lt;/EM&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-RIGHT-STYLE: none; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-LEFT-STYLE: none"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: gray"&gt;&lt;EM&gt;306.141&lt;/EM&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-RIGHT-STYLE: none; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-LEFT-STYLE: none"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: gray"&gt;&lt;EM&gt;1830.352&lt;/EM&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-RIGHT-STYLE: none; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-LEFT-STYLE: none"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: gray"&gt;&lt;EM&gt;2871.116&lt;/EM&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR style="HEIGHT: 40px"&gt;
&lt;TD style="PADDING-LEFT: 7px; PADDING-RIGHT: 7px"&gt;
&lt;P&gt;&lt;SPAN style="COLOR: black"&gt;&lt;STRONG&gt;DLINQ: data load options (headers)/compiled &lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="PADDING-LEFT: 7px; PADDING-RIGHT: 7px"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: black"&gt;6112.38&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="PADDING-LEFT: 7px; PADDING-RIGHT: 7px"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: black"&gt;6213.204&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="PADDING-LEFT: 7px; PADDING-RIGHT: 7px"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: black"&gt;472.648&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="PADDING-LEFT: 7px; PADDING-RIGHT: 7px"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: black"&gt;5784.032&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="PADDING-LEFT: 7px; PADDING-RIGHT: 7px"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: black"&gt;7345.794&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR style="BACKGROUND: #d3e0ef; HEIGHT: 19px"&gt;
&lt;TD style="BORDER-RIGHT-STYLE: none; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-LEFT-STYLE: none"&gt;
&lt;P&gt;&lt;SPAN style="COLOR: black"&gt;&lt;STRONG&gt;DLINQ: compiled &lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-RIGHT-STYLE: none; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-LEFT-STYLE: none"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: black"&gt;8458.7&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-RIGHT-STYLE: none; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-LEFT-STYLE: none"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: black"&gt;8693.848&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-RIGHT-STYLE: none; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-LEFT-STYLE: none"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: black"&gt;494.015&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-RIGHT-STYLE: none; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-LEFT-STYLE: none"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: black"&gt;8070.511&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-RIGHT-STYLE: none; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-LEFT-STYLE: none"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: black"&gt;9690.908&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR style="HEIGHT: 40px"&gt;
&lt;TD style="PADDING-LEFT: 7px; PADDING-RIGHT: 7px"&gt;
&lt;P&gt;&lt;SPAN style="COLOR: black"&gt;&lt;STRONG&gt;DLINQ: data load options (headers) &lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="PADDING-LEFT: 7px; PADDING-RIGHT: 7px"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: black"&gt;8657.555&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="PADDING-LEFT: 7px; PADDING-RIGHT: 7px"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: black"&gt;8685.617&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="PADDING-LEFT: 7px; PADDING-RIGHT: 7px"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: black"&gt;135.128&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="PADDING-LEFT: 7px; PADDING-RIGHT: 7px"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: black"&gt;8404.756&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="PADDING-LEFT: 7px; PADDING-RIGHT: 7px"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: black"&gt;8931.598&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR style="BACKGROUND: #d3e0ef; HEIGHT: 20px"&gt;
&lt;TD style="BORDER-RIGHT-STYLE: none; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-LEFT-STYLE: none"&gt;
&lt;P&gt;&lt;SPAN style="COLOR: black"&gt;&lt;STRONG&gt;DLINQ &lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-RIGHT-STYLE: none; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-LEFT-STYLE: none"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: black"&gt;9148.816&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-RIGHT-STYLE: none; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-LEFT-STYLE: none"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: black"&gt;9371.009&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-RIGHT-STYLE: none; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-LEFT-STYLE: none"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: black"&gt;509.871&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-RIGHT-STYLE: none; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-LEFT-STYLE: none"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: black"&gt;8833.747&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-RIGHT-STYLE: none; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-LEFT-STYLE: none"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: black"&gt;10461.56&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR style="HEIGHT: 40px"&gt;
&lt;TD style="PADDING-LEFT: 7px; PADDING-RIGHT: 7px"&gt;
&lt;P&gt;&lt;SPAN style="COLOR: gray"&gt;&lt;STRONG&gt;&lt;EM&gt;DLINQ: data load options (details)/no change tracking &lt;/EM&gt;&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="PADDING-LEFT: 7px; PADDING-RIGHT: 7px"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: gray"&gt;&lt;EM&gt;12069.17&lt;/EM&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="PADDING-LEFT: 7px; PADDING-RIGHT: 7px"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: gray"&gt;&lt;EM&gt;12212.82&lt;/EM&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="PADDING-LEFT: 7px; PADDING-RIGHT: 7px"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: gray"&gt;&lt;EM&gt;252.35&lt;/EM&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="PADDING-LEFT: 7px; PADDING-RIGHT: 7px"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: gray"&gt;&lt;EM&gt;11975.24&lt;/EM&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="PADDING-LEFT: 7px; PADDING-RIGHT: 7px"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: gray"&gt;&lt;EM&gt;12714.18&lt;/EM&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR style="BACKGROUND: #d3e0ef; HEIGHT: 40px"&gt;
&lt;TD style="BORDER-RIGHT-STYLE: none; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-LEFT-STYLE: none"&gt;
&lt;P&gt;&lt;SPAN style="COLOR: gray"&gt;&lt;STRONG&gt;&lt;EM&gt;DLINQ: data load options (details)/no change tracking/cache &lt;/EM&gt;&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-RIGHT-STYLE: none; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-LEFT-STYLE: none"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: gray"&gt;&lt;EM&gt;12176.1&lt;/EM&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-RIGHT-STYLE: none; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-LEFT-STYLE: none"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: gray"&gt;&lt;EM&gt;12330.98&lt;/EM&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-RIGHT-STYLE: none; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-LEFT-STYLE: none"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: gray"&gt;&lt;EM&gt;335.642&lt;/EM&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-RIGHT-STYLE: none; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-LEFT-STYLE: none"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: gray"&gt;&lt;EM&gt;12136.32&lt;/EM&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-RIGHT-STYLE: none; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-LEFT-STYLE: none"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: gray"&gt;&lt;EM&gt;13297.72&lt;/EM&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR style="HEIGHT: 40px"&gt;
&lt;TD style="BORDER-BOTTOM: #4f81bd 1pt solid; PADDING-LEFT: 7px; PADDING-RIGHT: 7px"&gt;
&lt;P&gt;&lt;SPAN style="COLOR: black"&gt;&lt;STRONG&gt;DLINQ: data load options (details) &lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-BOTTOM: #4f81bd 1pt solid; PADDING-LEFT: 7px; PADDING-RIGHT: 7px"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: black"&gt;12821.73&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-BOTTOM: #4f81bd 1pt solid; PADDING-LEFT: 7px; PADDING-RIGHT: 7px"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: black"&gt;12903.43&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-BOTTOM: #4f81bd 1pt solid; PADDING-LEFT: 7px; PADDING-RIGHT: 7px"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: black"&gt;394.513&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-BOTTOM: #4f81bd 1pt solid; PADDING-LEFT: 7px; PADDING-RIGHT: 7px"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: black"&gt;12476.51&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD style="BORDER-BOTTOM: #4f81bd 1pt solid; PADDING-LEFT: 7px; PADDING-RIGHT: 7px"&gt;
&lt;P style="TEXT-ALIGN: right"&gt;&lt;SPAN style="COLOR: black"&gt;13517.67&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;/DIV&gt;
&lt;P&gt;&lt;SPAN style="COLOR: #4f81bd; FONT-SIZE: 9pt"&gt;&lt;STRONG&gt;Table 2 Scenario 2: Read only customer and order entities &lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;The lines in Table 2 in grey show load options optimized for read-only scenarios, with the traditional DataSet implementation included for reference. Given the data for both scenarios several important observations can be made: &lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;Compilation of a query on a simple object graph has little impact to the performance of the query &lt;/LI&gt;
&lt;LI&gt;The object graph depth at which optimizations are performed matters significantly &lt;/LI&gt;
&lt;LI&gt;Not registering objects with the change tracker affects overall performance significantly &lt;/LI&gt;
&lt;LI&gt;Optimized correctly, LINQ to SQL performance meets expectations &lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;In the first observation, we see that for scenario the second query compilation positively affects the performance of data loading such that when the query is compiled into a variable, along with any methods required, for later use. When the resulting expression is invoked, the cost for preparing the object graph and associated methods has already been performed (some elements of the query can be changed for variables), but no jitting is performed, resulting in gains of over 85.6% when compared to a straight LINQ to SQL implementation. &lt;/P&gt;
&lt;P&gt;Additionally we find that the level that the data load options are placed in the object graph dramatically affects the performance of the query. The leading LINQ to SQL scenario has optimizations placed on the relationship between the Customer entity and the SalesOrderDetails entity such that when a Customer entity is loaded so are the related sales order headers, the order details, and the resulting products. Table 2 shows the outcome of placing the load optimization on the details resulting in a performance increase over other LINQ to SQL methods with different or no optimizations. &lt;/P&gt;
&lt;P&gt;In the third observation, we also see that in instances where the context is not tracking object changes (and results are read-only) the code can execute faster, although in some instances not significantly. For the first scenario, toggling the change tracking feature resulted in about 7.5% performance gain. However, we also see that changing the query to use a projection, reducing the amount of data materialized, in addition to disabling change tracking, resulted in further gains—consistently exceeding the ADO.NET DataReader performance. &lt;/P&gt;
&lt;P&gt;As another point of comparison, the two fastest implementations from ADO.NET and LINQ to SQL are below. &lt;/P&gt;
&lt;DIV&gt;
&lt;TABLE style="BORDER-COLLAPSE: collapse" border=0&gt;
&lt;COLGROUP&gt;
&lt;COL style="WIDTH: 638px"&gt;&lt;/COLGROUP&gt;
&lt;TBODY vAlign=top&gt;
&lt;TR&gt;
&lt;TD style="BORDER-BOTTOM: black 0.5pt solid; BORDER-LEFT: black 0.5pt solid; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-TOP: black 0.5pt solid; BORDER-RIGHT: black 0.5pt solid"&gt;
&lt;DIV id=codeSnippetWrapper&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: '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&gt;&lt;SPAN style="COLOR: #0000ff"&gt;object&lt;/SPAN&gt;[] customerValues = &lt;SPAN style="COLOR: #0000ff"&gt;null&lt;/SPAN&gt;; &lt;BR&gt;List&amp;lt;&lt;SPAN style="COLOR: #0000ff"&gt;object&lt;/SPAN&gt;[]&amp;gt; salesHeaderValues = &lt;SPAN style="COLOR: #0000ff"&gt;null&lt;/SPAN&gt;; &lt;BR&gt;List&amp;lt;&lt;SPAN style="COLOR: #0000ff"&gt;object&lt;/SPAN&gt;[]&amp;gt; salesDetailValues = &lt;SPAN style="COLOR: #0000ff"&gt;null&lt;/SPAN&gt;; &lt;BR&gt;List&amp;lt;&lt;SPAN style="COLOR: #0000ff"&gt;object&lt;/SPAN&gt;[]&amp;gt; salesDetailProductValues = &lt;SPAN style="COLOR: #0000ff"&gt;null&lt;/SPAN&gt;; &lt;BR&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #0000ff"&gt;using&lt;/SPAN&gt;( var connection = &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; SqlConnection(AdventureWorksConnectionString ) ) &lt;BR&gt;{ &lt;BR&gt;    &lt;SPAN style="COLOR: #0000ff"&gt;using&lt;/SPAN&gt;( var command = &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; SqlCommand( &lt;SPAN style="COLOR: #006080"&gt;"SELECT [t0].[CustomerID], [t0].[AccountNumber], [t0].[rowguid], [t0].[ModifiedDate] FROM [Sales].[Customer] AS [t0] WHERE [t0].[CustomerID] = @p0"&lt;/SPAN&gt; ) ) &lt;BR&gt;    { &lt;BR&gt;        command.Parameters.AddWithValue( &lt;SPAN style="COLOR: #006080"&gt;"@p0"&lt;/SPAN&gt;, 29475 ); &lt;BR&gt;        command.Connection = connection; &lt;BR&gt;        connection.Open(); &lt;BR&gt;&lt;BR&gt;        var dr = command.ExecuteReader( System.Data.CommandBehavior.CloseConnection ); &lt;BR&gt;        customerValues = &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;object&lt;/SPAN&gt;[ dr.FieldCount ]; &lt;BR&gt;        &lt;BR&gt;        &lt;SPAN style="COLOR: #0000ff"&gt;while&lt;/SPAN&gt;( dr.Read() ) &lt;BR&gt;        { &lt;BR&gt;            dr.GetValues( customerValues ); &lt;BR&gt;        } &lt;BR&gt;        connection.Close(); &lt;BR&gt;    } &lt;BR&gt;} &lt;BR&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #0000ff"&gt;using&lt;/SPAN&gt;( var connection = &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; SqlConnection(AdventureWorksConnectionString ) ) &lt;BR&gt;{ &lt;BR&gt;    &lt;SPAN style="COLOR: #0000ff"&gt;using&lt;/SPAN&gt;( var command = &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; SqlCommand( &lt;SPAN style="COLOR: #006080"&gt;"SELECT [t0].[SalesOrderID], [t0].[RevisionNumber], &lt;BR&gt;            [t0].[OrderDate], [t0].[DueDate], [t0].[ShipDate], [t0].[Status], &lt;BR&gt;            [t0].[OnlineOrderFlag], [t0].[SalesOrderNumber], [t0].[PurchaseOrderNumber], &lt;BR&gt;            [t0].[AccountNumber], [t0].[CustomerID], [t0].[SubTotal], [t0].[TaxAmt], &lt;BR&gt;            [t0].[Freight], [t0].[TotalDue], [t0].[Comment], [t0].[rowguid], &lt;BR&gt;            [t0].[ModifiedDate] FROM [Sales].[SalesOrderHeader] AS [t0] WHERE &lt;BR&gt;            [t0].[CustomerID] = @x1"&lt;/SPAN&gt; ) ) &lt;BR&gt;    { &lt;BR&gt;        command.Connection = connection; &lt;BR&gt;        command.Parameters.AddWithValue( &lt;SPAN style="COLOR: #006080"&gt;"@x1"&lt;/SPAN&gt;, customerValues[ 0 ] ); &lt;BR&gt;        connection.Open(); &lt;BR&gt;&lt;BR&gt;        var dr = command.ExecuteReader( System.Data.CommandBehavior.CloseConnection ); &lt;BR&gt;        salesHeaderValues = &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; List&amp;lt;&lt;SPAN style="COLOR: #0000ff"&gt;object&lt;/SPAN&gt;[]&amp;gt;( 16 ); &lt;BR&gt;        &lt;SPAN style="COLOR: #0000ff"&gt;while&lt;/SPAN&gt;( dr.Read() ) &lt;BR&gt;        { &lt;BR&gt;            var salesHeaderRowValues = &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;object&lt;/SPAN&gt;[ dr.FieldCount ]; &lt;BR&gt;            dr.GetValues( salesHeaderRowValues ); &lt;BR&gt;            salesHeaderValues.Add( salesHeaderRowValues ); &lt;BR&gt;        } &lt;BR&gt;        connection.Close(); &lt;BR&gt;    } &lt;BR&gt;} &lt;BR&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #0000ff"&gt;using&lt;/SPAN&gt;( var connection = &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; SqlConnection(AdventureWorksConnectionString ) ) &lt;BR&gt;{ &lt;BR&gt;    &lt;SPAN style="COLOR: #0000ff"&gt;using&lt;/SPAN&gt;( var command = &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; SqlCommand( &lt;SPAN style="COLOR: #006080"&gt;"SELECT [t0].[SalesOrderID], &lt;BR&gt;        [t0].[SalesOrderDetailID], [t0].[CarrierTrackingNumber], [t0].[OrderQty], &lt;BR&gt;        [t0].[ProductID], [t0].[UnitPrice], [t0].[LineTotal], [t0].[rowguid], &lt;BR&gt;        [t0].[ModifiedDate] FROM [Sales].[SalesOrderDetail] AS [t0] WHERE &lt;BR&gt;        [t0].[SalesOrderID] = @p0"&lt;/SPAN&gt; ) ) &lt;BR&gt;    { &lt;BR&gt;        command.Connection = connection; &lt;BR&gt;        command.Parameters.AddWithValue( &lt;SPAN style="COLOR: #006080"&gt;"@p0"&lt;/SPAN&gt;, salesHeaderValues[ 0 ][ 0 ] ); &lt;BR&gt;        connection.Open(); &lt;BR&gt;&lt;BR&gt;        var dr = command.ExecuteReader( System.Data.CommandBehavior.CloseConnection ); &lt;BR&gt;        salesDetailValues = &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; List&amp;lt;&lt;SPAN style="COLOR: #0000ff"&gt;object&lt;/SPAN&gt;[]&amp;gt;( 16 ); &lt;BR&gt;        &lt;SPAN style="COLOR: #0000ff"&gt;while&lt;/SPAN&gt;( dr.Read() ) &lt;BR&gt;        { &lt;BR&gt;            var salesDetailRowValues = &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;object&lt;/SPAN&gt;[ dr.FieldCount ]; &lt;BR&gt;            dr.GetValues( salesDetailRowValues ); &lt;BR&gt;            salesDetailValues.Add( salesDetailRowValues ); &lt;BR&gt;        } &lt;BR&gt;        connection.Close(); &lt;BR&gt;    } &lt;BR&gt;} &lt;BR&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #0000ff"&gt;using&lt;/SPAN&gt;( var connection = &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; SqlConnection(AdventureWorksConnectionString ) ) &lt;BR&gt;{ &lt;BR&gt;    &lt;SPAN style="COLOR: #0000ff"&gt;using&lt;/SPAN&gt;( var command = &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; SqlCommand( &lt;SPAN style="COLOR: #006080"&gt;"SELECT [t0].[ProductID], [t0].[Name], &lt;BR&gt;            [t0].[ProductNumber], [t0].[MakeFlag], [t0].[FinishedGoodsFlag], [t0].[Color], &lt;BR&gt;            [t0].[SafetyStockLevel], [t0].[ReorderPoint], [t0].[StandardCost], &lt;BR&gt;            [t0].[ListPrice], [t0].[Size], [t0].[SizeUnitMeasureCode], &lt;BR&gt;            [t0].[WeightUnitMeasureCode], [t0].[Weight], [t0].[DaysToManufacture], &lt;BR&gt;            [t0].[ProductLine], [t0].[Class], [t0].[Style], [t0].[ProductSubcategoryID], &lt;BR&gt;            [t0].[ProductModelID], [t0].[SellStartDate], [t0].[SellEndDate], &lt;BR&gt;            [t0].[DiscontinuedDate], [t0].[rowguid], [t0].[ModifiedDate] FROM &lt;BR&gt;            [Production].[Product] AS [t0] WHERE [t0].[ProductID] = @p0"&lt;/SPAN&gt; ) ) &lt;BR&gt;    { &lt;BR&gt;        command.Connection = connection; &lt;BR&gt;        command.Parameters.AddWithValue( &lt;SPAN style="COLOR: #006080"&gt;"@p0"&lt;/SPAN&gt;, salesDetailValues[ 0 ][ 4 ] ); &lt;BR&gt;        connection.Open(); &lt;BR&gt;&lt;BR&gt;&lt;BR&gt;        var dr = command.ExecuteReader( System.Data.CommandBehavior.CloseConnection ); &lt;BR&gt;        salesDetailProductValues = &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; List&amp;lt;&lt;SPAN style="COLOR: #0000ff"&gt;object&lt;/SPAN&gt;[]&amp;gt;( 16 ); &lt;BR&gt;        &lt;SPAN style="COLOR: #0000ff"&gt;while&lt;/SPAN&gt;( dr.Read() ) &lt;BR&gt;        { &lt;BR&gt;            var salesDetailProductRowValues = &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;object&lt;/SPAN&gt;[ dr.FieldCount ]; &lt;BR&gt;            dr.GetValues( salesDetailProductRowValues ); &lt;BR&gt;            salesDetailProductValues.Add( salesDetailProductRowValues ); &lt;BR&gt;        } &lt;BR&gt;        connection.Close(); &lt;BR&gt;    } &lt;BR&gt;}&lt;/PRE&gt;&lt;/DIV&gt;
&lt;P&gt;&lt;SPAN style="FONT-FAMILY: courier new; FONT-SIZE: 8pt"&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;/DIV&gt;
&lt;P&gt;&lt;SPAN style="COLOR: #4f81bd; FONT-SIZE: 9pt"&gt;&lt;STRONG&gt;Figure 3 Scenario 2 using ADO.NET DataReader &lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;Much like the previous example, the ADO.NET version is more verbose and includes embedded TSQL statements for data retrieval, totaling nearly 50 lines of code. &lt;/P&gt;
&lt;DIV&gt;
&lt;TABLE style="BORDER-COLLAPSE: collapse" border=0&gt;
&lt;COLGROUP&gt;
&lt;COL style="WIDTH: 638px"&gt;&lt;/COLGROUP&gt;
&lt;TBODY vAlign=top&gt;
&lt;TR&gt;
&lt;TD style="BORDER-BOTTOM: black 0.5pt solid; BORDER-LEFT: black 0.5pt solid; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-TOP: black 0.5pt solid; BORDER-RIGHT: black 0.5pt solid"&gt;
&lt;DIV id=codeSnippetWrapper&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: '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&gt;&lt;SPAN style="COLOR: #0000ff"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;static&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;readonly&lt;/SPAN&gt; Func&amp;lt;AdventureWorksDataContext, &lt;SPAN style="COLOR: #0000ff"&gt;int&lt;/SPAN&gt;, Customer&amp;gt; CustomerWithSalesOrderDetails = &lt;BR&gt;CompiledQuery.Compile( &lt;BR&gt;    ( AdventureWorksDataContext context, &lt;SPAN style="COLOR: #0000ff"&gt;int&lt;/SPAN&gt; identifier ) =&amp;gt; &lt;BR&gt;            context.Customers.Single( c =&amp;gt; c.CustomerID == identifier ) &lt;BR&gt;    ); &lt;BR&gt;&lt;BR&gt;&lt;SPAN style="COLOR: #0000ff"&gt;using&lt;/SPAN&gt;( var context = &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; DataClasses1DataContext() ) &lt;BR&gt;{ &lt;BR&gt;    var dlo = &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; DataLoadOptions(); &lt;BR&gt;    dlo.LoadWith&amp;lt;Customer&amp;gt;( c =&amp;gt; c.SalesOrderHeaders ); &lt;BR&gt;    dlo.LoadWith&amp;lt;SalesOrderHeader&amp;gt;( soh =&amp;gt; soh.SalesOrderDetails ); &lt;BR&gt;    dlo.LoadWith&amp;lt;SalesOrderDetail&amp;gt;( sod =&amp;gt; sod.Products ); &lt;BR&gt;&lt;BR&gt;    context.ObjectTrackingEnabled = &lt;SPAN style="COLOR: #0000ff"&gt;false&lt;/SPAN&gt;; &lt;BR&gt;    context.DeferredLoadingEnabled = &lt;SPAN style="COLOR: #0000ff"&gt;false&lt;/SPAN&gt;; &lt;BR&gt;    context.LoadOptions = dlo; &lt;BR&gt;&lt;BR&gt;    customer = CustomerWithSalesOrderDetails(context, 29475); &lt;BR&gt;    headers = customer.SalesOrderHeaders.ToArray(); &lt;BR&gt;    header = headers.First(); &lt;BR&gt;    details = header.SalesOrderDetails.ToArray(); &lt;BR&gt;    products = details.Select( sod =&amp;gt; sod.Products ).ToArray(); &lt;BR&gt;}&lt;/PRE&gt;&lt;SPAN style="FONT-FAMILY: courier new; FONT-SIZE: 8pt"&gt;&lt;/SPAN&gt;&lt;/DIV&gt;&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;/DIV&gt;
&lt;P&gt;&lt;SPAN style="COLOR: #4f81bd; FONT-SIZE: 9pt"&gt;&lt;STRONG&gt;Figure 4 Scenario 2 using LINQ to SQL &lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;Conversely, the same result is achieved with 14 lines of code with LINQ to SQL. &lt;/P&gt;
&lt;H1&gt;Caching &lt;/H1&gt;
&lt;P&gt;To this point, all of the tests and observations have been made against contexts with short lifetimes and in our scenarios, it has worked fine. However, in some other scenarios having to load fairly static data repeatedly may produce unnecessary overhead and slow the performance of the application down. &lt;/P&gt;
&lt;P&gt;To optimize for this, LINQ to SQL includes an identity cache such that when an entity is retrieved it is automatically inserted into this cache. If you run another query where results overlap with an entity that has already been materialized in the same context, the entity is returned from the identity cache instead of the source data store except if using a projection. &lt;/P&gt;
&lt;P&gt;Let us extend the second scenario such that the customer calls into a call center to check the status of the order, where an operator uses a Windows application to view/update the order on behalf of the customer. Given that, operators are reusing the same reference data repeatedly (such as product information, country, region, state, and province); it seems inefficient to reload the data for every screen that requires it. &lt;/P&gt;
&lt;H1&gt;Custom Object Pooling &lt;/H1&gt;
&lt;P&gt;To work around these issues, a crude object pool was created using the HttpRuntime.Cache object to store reference information. Additionally some modifications were also made to the objects to accommodate lazy lookups of reference data without violating the integrity of the developer experience. &lt;/P&gt;
&lt;DIV&gt;
&lt;TABLE style="BORDER-COLLAPSE: collapse" border=0&gt;
&lt;COLGROUP&gt;
&lt;COL style="WIDTH: 638px"&gt;&lt;/COLGROUP&gt;
&lt;TBODY vAlign=top&gt;
&lt;TR&gt;
&lt;TD style="BORDER-BOTTOM: black 0.5pt solid; BORDER-LEFT: black 0.5pt solid; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-TOP: black 0.5pt solid; BORDER-RIGHT: black 0.5pt solid"&gt;
&lt;DIV id=codeSnippetWrapper&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: '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&gt;[Association(Name=&lt;SPAN style="COLOR: #006080"&gt;"SalesOrderDetail_Product"&lt;/SPAN&gt;, Storage=&lt;SPAN style="COLOR: #006080"&gt;"_Products"&lt;/SPAN&gt;, ThisKey=&lt;SPAN style="COLOR: #006080"&gt;"ProductID"&lt;/SPAN&gt;, OtherKey=&lt;SPAN style="COLOR: #006080"&gt;"ProductID"&lt;/SPAN&gt;, IsUnique=&lt;SPAN style="COLOR: #0000ff"&gt;true&lt;/SPAN&gt;, IsForeignKey=&lt;SPAN style="COLOR: #0000ff"&gt;false&lt;/SPAN&gt;)] &lt;BR&gt;&lt;SPAN style="COLOR: #0000ff"&gt;public&lt;/SPAN&gt; Product Product &lt;BR&gt;{ &lt;BR&gt;    get { &lt;SPAN style="COLOR: #0000ff"&gt;return&lt;/SPAN&gt; _Product.Entity; } &lt;BR&gt;    set { &lt;BR&gt;            var previousValue = _Product.Entity; &lt;BR&gt;            &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; ((previousValue != &lt;SPAN style="COLOR: #0000ff"&gt;value&lt;/SPAN&gt;) || (_Product.HasLoadedOrAssignedValue == &lt;SPAN style="COLOR: #0000ff"&gt;false&lt;/SPAN&gt;)) &lt;BR&gt;            { &lt;BR&gt;                SendPropertyChanging(); &lt;BR&gt;&lt;BR&gt;                &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; ((previousValue != &lt;SPAN style="COLOR: #0000ff"&gt;null&lt;/SPAN&gt;)) &lt;BR&gt;                { &lt;BR&gt;                    _Product.Entity = &lt;SPAN style="COLOR: #0000ff"&gt;null&lt;/SPAN&gt;; &lt;BR&gt;                    previousValue.SalesOrderDetail = &lt;SPAN style="COLOR: #0000ff"&gt;null&lt;/SPAN&gt;; &lt;BR&gt;                } &lt;BR&gt;&lt;BR&gt;                _Product.Entity = &lt;SPAN style="COLOR: #0000ff"&gt;value&lt;/SPAN&gt;; &lt;BR&gt;                &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; ((&lt;SPAN style="COLOR: #0000ff"&gt;value&lt;/SPAN&gt; != &lt;SPAN style="COLOR: #0000ff"&gt;null&lt;/SPAN&gt;)) &lt;BR&gt;                { &lt;BR&gt;                    &lt;SPAN style="COLOR: #0000ff"&gt;value&lt;/SPAN&gt;.SalesOrderDetail = &lt;SPAN style="COLOR: #0000ff"&gt;this&lt;/SPAN&gt;; &lt;BR&gt;                } &lt;BR&gt;&lt;BR&gt;                SendPropertyChanged(&lt;SPAN style="COLOR: #006080"&gt;"Product"&lt;/SPAN&gt;); &lt;BR&gt;            } &lt;BR&gt;        } &lt;BR&gt;} &lt;/PRE&gt;&lt;SPAN style="FONT-FAMILY: courier new; FONT-SIZE: 8pt"&gt;&lt;/SPAN&gt;&lt;/DIV&gt;&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;/DIV&gt;
&lt;P&gt;&lt;SPAN style="COLOR: #4f81bd; FONT-SIZE: 9pt"&gt;&lt;STRONG&gt;Figure 5 Entity relationship for LINQ to SQL &lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;DIV id=codeSnippetWrapper&gt;&lt;BR&gt;&lt;/DIV&gt;
&lt;DIV&gt;
&lt;TABLE style="BORDER-COLLAPSE: collapse" border=0&gt;
&lt;TBODY vAlign=top&gt;
&lt;TR&gt;
&lt;TD style="BORDER-BOTTOM: black 0.5pt solid; BORDER-LEFT: black 0.5pt solid; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-TOP: black 0.5pt solid; BORDER-RIGHT: black 0.5pt solid"&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: '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&gt;&lt;SPAN style="COLOR: #0000ff"&gt;public&lt;/SPAN&gt; Product Product2 &lt;BR&gt;{ &lt;BR&gt;    get { &lt;SPAN style="COLOR: #0000ff"&gt;return&lt;/SPAN&gt; EntityCache.GetOrAdd&amp;lt;Product&amp;gt;( p =&amp;gt; p.ProductID == ProductID ).FirstOrDefault(); } &lt;BR&gt;    set { &lt;BR&gt;            SendPropertyChanging(); &lt;BR&gt;&lt;BR&gt;            &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt;( &lt;SPAN style="COLOR: #0000ff"&gt;value&lt;/SPAN&gt; == &lt;SPAN style="COLOR: #0000ff"&gt;null&lt;/SPAN&gt; ) &lt;BR&gt;            {&lt;BR&gt;                ProductID = 0; &lt;BR&gt;            }&lt;BR&gt;            &lt;SPAN style="COLOR: #0000ff"&gt;else&lt;/SPAN&gt; &lt;BR&gt;            {&lt;BR&gt;                ProductID = &lt;SPAN style="COLOR: #0000ff"&gt;value&lt;/SPAN&gt;.ProductID; &lt;BR&gt;                SendPropertyChanged( &lt;SPAN style="COLOR: #006080"&gt;"Product2"&lt;/SPAN&gt; ); &lt;BR&gt;            } &lt;BR&gt;        }&lt;BR&gt;}&lt;/PRE&gt;
&lt;P&gt;&lt;SPAN style="FONT-FAMILY: courier new; FONT-SIZE: 8pt"&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;/DIV&gt;
&lt;P&gt;&lt;SPAN style="COLOR: #4f81bd; FONT-SIZE: 9pt"&gt;&lt;STRONG&gt;Figure 6 Entity relationship for cache &lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;The EntityCache type, where the data is loaded from a context and stored in the local cache object, performs the work. The property accessors were updated on the entity to use the different means of managing the entity relationships due to issues with associating entities from multiple contexts together. Since LINQ to SQL really translates strongly typed entity properties to foreign keys, the keys are manipulated manually in the updated property. &lt;/P&gt;
&lt;P&gt;The data showing the overhead of such an operation is shown in Table 2, where the caching method is 12% slower, but results in less data retransmitted over the network (each product in this case is about 1KB) and still performs the same or better than a straight data reader. While the performance degradation over 1KB of data is hardly persuasive, applied to our extension of scenario 2 where operators are loading the same reference data repeatedly may result in significant performance gains. &lt;/P&gt;&lt;SPAN class=technoratitag&gt;Technorati Tags: &lt;A title="Link to Technorati Tag category for data" href="http://www.technorati.com/tag/data" rel=tag target=_blank mce_href="http://www.technorati.com/tag/data"&gt;data&lt;/A&gt;, &lt;A title="Link to Technorati Tag category for sql" href="http://www.technorati.com/tag/sql" rel=tag target=_blank mce_href="http://www.technorati.com/tag/sql"&gt;sql&lt;/A&gt;, &lt;A title="Link to Technorati Tag category for linq" href="http://www.technorati.com/tag/linq" rel=tag target=_blank mce_href="http://www.technorati.com/tag/linq"&gt;linq&lt;/A&gt;, &lt;A title="Link to Technorati Tag category for dlinq" href="http://www.technorati.com/tag/dlinq" rel=tag target=_blank mce_href="http://www.technorati.com/tag/dlinq"&gt;dlinq&lt;/A&gt;, &lt;A title="Link to Technorati Tag category for linq to sql" href="http://www.technorati.com/tag/linq+to+sql" rel=tag target=_blank mce_href="http://www.technorati.com/tag/linq+to+sql"&gt;linq to sql&lt;/A&gt;, &lt;A title="Link to Technorati Tag category for ado.net" href="http://www.technorati.com/tag/ado.net" rel=tag target=_blank mce_href="http://www.technorati.com/tag/ado.net"&gt;ado.net&lt;/A&gt;, &lt;A title="Link to Technorati Tag category for performance" href="http://www.technorati.com/tag/performance" rel=tag target=_blank mce_href="http://www.technorati.com/tag/performance"&gt;performance&lt;/A&gt;, &lt;A title="Link to Technorati Tag category for load options" href="http://www.technorati.com/tag/load+options" rel=tag target=_blank mce_href="http://www.technorati.com/tag/load+options"&gt;load options&lt;/A&gt;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN class=sociallinks&gt;Add to: | &lt;A href="http://technorati.com/faves?add=http%3A%2F%2Fblogs%2Emsdn%2Ecom%2Frimuri%2Farchive%2F2009%2F09%2F01%2Fbuilding%2Dperformant%2Dline%2Dof%2Dbusiness%2Dapplications%2Dwith%2Dlinq%2Dto%2Dsql%2Easpx" target=_blank mce_href="http://technorati.com/faves?add=http%3A%2F%2Fblogs%2Emsdn%2Ecom%2Frimuri%2Farchive%2F2009%2F09%2F01%2Fbuilding%2Dperformant%2Dline%2Dof%2Dbusiness%2Dapplications%2Dwith%2Dlinq%2Dto%2Dsql%2Easpx"&gt;Technorati&lt;/A&gt; | &lt;A href="http://digg.com/submit?phase=2&amp;amp;url=http%3A%2F%2Fblogs%2Emsdn%2Ecom%2Frimuri%2Farchive%2F2009%2F09%2F01%2Fbuilding%2Dperformant%2Dline%2Dof%2Dbusiness%2Dapplications%2Dwith%2Dlinq%2Dto%2Dsql%2Easpx" target=_blank mce_href="http://digg.com/submit?phase=2&amp;amp;url=http%3A%2F%2Fblogs%2Emsdn%2Ecom%2Frimuri%2Farchive%2F2009%2F09%2F01%2Fbuilding%2Dperformant%2Dline%2Dof%2Dbusiness%2Dapplications%2Dwith%2Dlinq%2Dto%2Dsql%2Easpx"&gt;Digg&lt;/A&gt; | &lt;A href="http://del.icio.us/post?url=http%3A%2F%2Fblogs%2Emsdn%2Ecom%2Frimuri%2Farchive%2F2009%2F09%2F01%2Fbuilding%2Dperformant%2Dline%2Dof%2Dbusiness%2Dapplications%2Dwith%2Dlinq%2Dto%2Dsql%2Easpx;title=Building%20Performant%20Line%20of%20Business%20Applications%20with%20LINQ%20to%20SQL" target=_blank mce_href="http://del.icio.us/post?url=http%3A%2F%2Fblogs%2Emsdn%2Ecom%2Frimuri%2Farchive%2F2009%2F09%2F01%2Fbuilding%2Dperformant%2Dline%2Dof%2Dbusiness%2Dapplications%2Dwith%2Dlinq%2Dto%2Dsql%2Easpx;title=Building%20Performant%20Line%20of%20Business%20Applications%20with%20LINQ%20to%20SQL"&gt;del.icio.us&lt;/A&gt; | &lt;A href="http://reddit.com/submit?url=http%3A%2F%2Fblogs%2Emsdn%2Ecom%2Frimuri%2Farchive%2F2009%2F09%2F01%2Fbuilding%2Dperformant%2Dline%2Dof%2Dbusiness%2Dapplications%2Dwith%2Dlinq%2Dto%2Dsql%2Easpx&amp;amp;title=Building%20Performant%20Line%20of%20Business%20Applications%20with%20LINQ%20to%20SQL" target=_blank mce_href="http://reddit.com/submit?url=http%3A%2F%2Fblogs%2Emsdn%2Ecom%2Frimuri%2Farchive%2F2009%2F09%2F01%2Fbuilding%2Dperformant%2Dline%2Dof%2Dbusiness%2Dapplications%2Dwith%2Dlinq%2Dto%2Dsql%2Easpx&amp;amp;title=Building%20Performant%20Line%20of%20Business%20Applications%20with%20LINQ%20to%20SQL"&gt;reddit&lt;/A&gt; | &lt;/SPAN&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9885587" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/rimuri/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/rimuri/archive/tags/LINQ+to+SQL+_2800_DLINQ_2900_/default.aspx">LINQ to SQL (DLINQ)</category><category domain="http://blogs.msdn.com/rimuri/archive/tags/Lambda+Expressions/default.aspx">Lambda Expressions</category></item><item><title>Building Line of Business Applications with LINQ to SQL</title><link>http://blogs.msdn.com/rimuri/archive/2009/08/26/building-line-of-business-applications-with-linq-to-sql.aspx</link><pubDate>Wed, 26 Aug 2009 19:49:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9885575</guid><dc:creator>Richard Murillo</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/rimuri/comments/9885575.aspx</comments><wfw:commentRss>http://blogs.msdn.com/rimuri/commentrss.aspx?PostID=9885575</wfw:commentRss><wfw:comment>http://blogs.msdn.com/rimuri/rsscomments.aspx?PostID=9885575</wfw:comment><description>&lt;H3&gt;&lt;A title=_Toc213640086 name=_Toc213640086&gt;&lt;/A&gt;Introduction&lt;/H3&gt;
&lt;P&gt;The LINQ framework offers a basic pattern of sequence operators, allowing for primitive behavior such as filtering, grouping, and joining over collections and types. The support of the high level query comprehension syntax in C# 3.0 is paramount to developing an application quickly and allows for transparent development practices for developers where querying an in-memory collection or a remote database works the same. &lt;/P&gt;
&lt;P&gt;While LINQ to SQL provides necessary services for radically simplifying how developers write applications, it has some shortcomings. &lt;/P&gt;
&lt;H3&gt;&lt;A title=_Toc213640087 name=_Toc213640087&gt;&lt;/A&gt;Why use LINQ to SQL?&lt;/H3&gt;
&lt;P&gt;To provide a sustainable model for future support, an object model was created to match the business entities used by the application. Having dependencies on tables and views in our relational database, the objects required “mapping” from the relational world to the object world, which was achieved using LINQ to SQL.&lt;/P&gt;
&lt;P&gt;LINQ to SQL provides a simple mapping between tables, columns, and relationships to classes, fields, and collection properties (for relationships) that allow for “ease of use” programming at the cost of composability. Composability was lost due to the nature of databases and the limitations of LINQ to SQL such that relational databases relate tables via foreign key relationships where individual entities need not concern themselves with relationships (such as Customers to Orders); however, when mapping tables to classes the relationships are defined in advance.&lt;/P&gt;
&lt;P&gt;Further, the use of classes mapped to tables allow for database abstraction and suit the needs of rapid application development such that the framework ensures correct database create, read, update, and delete statements are issued after changes are made to objects through the use of change tracking mechanisms.&lt;/P&gt;
&lt;H3&gt;&lt;A title=_Toc213640088 name=_Toc213640088&gt;&lt;/A&gt;LINQ to SQL Architecture Limitations&lt;/H3&gt;
&lt;P&gt;LINQ to SQL does not have a good story with distribution and concurrency such that new application design patterns for “cloud computing” do not translate well. Entities can be detached, attached, and moved around various layers in applications but are not truly portable (Strahl, 2007) and are really only for single-tier or partitioned &lt;A&gt;multitier-esque &lt;/A&gt;solutions.&lt;/P&gt;
&lt;H3&gt;&lt;A title=_Toc213640089 name=_Toc213640089&gt;&lt;/A&gt;Multi-threading&lt;/H3&gt;
&lt;P&gt;LINQ to SQL (or LINQ for that matter) does not natively support distributed parallel queries. LINQ queries are translated to SQL statements and objects are materialized when required from the data stream. By design the LINQ to SQL DataContext class is not thread-safe and was not meant to be shared, however, compiled queries are thread safe and can be used with separate data contexts.&lt;/P&gt;
&lt;H3&gt;&lt;A title=_Toc213640090 name=_Toc213640090&gt;&lt;/A&gt;Forward only (reference) data&lt;/H3&gt;
&lt;P&gt;It is not uncommon for applications to include varying amounts of reference data used to assist the user in making a decision. This can commonly be seen in contact card scenarios where address details are bound to combo boxes (such as states or provinces and countries or regions). &lt;/P&gt;
&lt;P&gt;The general guidance for using LINQ to SQL is to use short lived data contexts, where the data context is discarded after each unit of work operation. The fundamental issue encountered with this approach is entities that have data stored in the database and are materialized cannot be attached or associated to a new data context and therefore must be loaded with each new data context. The approach is valid and introduces a trivial amount of overhead when loading small or moderate amounts of data. However, in several instances our application can have large amounts of data loaded and bound, producing a noticeable delay when loading records.&lt;/P&gt;
&lt;P&gt;To work around the short data context lifetime an object pool was created to store the values loaded from the database. All classes that used the reference data were modified to exclude the specific 1:1 foreign key attributes (effectively making a simple property) for LINQ to SQL. The contents of the property retrieved the appropriate value from the object pool, based on the foreign key identity, during retrieval and likewise updated the foreign key value during a set operation. &lt;/P&gt;
&lt;H3&gt;&lt;A title=_Toc213640091 name=_Toc213640091&gt;&lt;/A&gt;Concurrency&lt;/H3&gt;
&lt;P&gt;Through the use of time stamps on rows in our relational database, the system makes use of optimistic concurrency. When LINQ to SQL detects a concurrency conflict, an exception is raised where the list of conflicting objects can be retrieved.&lt;/P&gt;
&lt;H4&gt;&lt;A title=_Toc213640092 name=_Toc213640092&gt;&lt;/A&gt;Issues with time stamps&lt;/H4&gt;
&lt;P&gt;While using time stamps an issue arose that caused significant issues with the application:&lt;/P&gt;
&lt;P&gt;1. Multiple entities with time stamp properties are updated in a context&lt;/P&gt;
&lt;P&gt;2. During change submission conflicts occur for some of the entities but not all&lt;/P&gt;
&lt;P&gt;3. The raised change conflict exception is caught and the conflicts are resolved&lt;/P&gt;
&lt;P&gt;4. Change submission is requested now that conflicts are resolved and an exception is raised indicating the generated time stamp has been updated&lt;/P&gt;
&lt;P&gt;The fundamental issue is one buried inside the LINQ to SQL framework—after processing the first change submission the properties are updated on the entities that are not in conflict. When the exception is raised the time stamp property is not reset to its original (due to the failure on submission) and left in a modified state. (Parra, 2008)&lt;/P&gt;
&lt;P&gt;There are multiple workarounds for this issue:&lt;/P&gt;
&lt;P&gt;&lt;B&gt;1. &lt;/B&gt;&lt;B&gt;Do not use time stamps for concurrency or disable automatic synchronization. &lt;/B&gt;Automatic synchronization can be disabled for update scenarios (or disabled completely) by changing a parameter on the property’s attribute. If synchronization is disabled for update operations, the issue is avoided; however, the time stamp property is uncoordinated with the database (Kulkarni, 2008), (Parra, 2008). This can be resolved in several different ways:&lt;B&gt;&lt;/B&gt;&lt;/P&gt;
&lt;P&gt;&lt;B&gt;a. &lt;/B&gt;&lt;B&gt;Resolve the concurrency conflict by merging the entity.&lt;/B&gt; A concurrency conflict exception is raised on the next call to submit changes and can be handled by merging the changed values with the database values (effectively refreshing the time stamp while keeping the user changes).&lt;B&gt;&lt;/B&gt;&lt;/P&gt;
&lt;P&gt;&lt;B&gt;b. &lt;/B&gt;&lt;B&gt;Proactively refresh the entity after the update operation. &lt;/B&gt;Once the update operation has completed issue a refresh for the entity to coordinate the time stamp values (Parra, 2008).&lt;B&gt;&lt;/B&gt;&lt;/P&gt;
&lt;P&gt;&lt;B&gt;c. &lt;/B&gt;&lt;B&gt;Discard the DataContext that materialized the entity. &lt;/B&gt;After the changes submit successfully the data context can be disposed. Future queries for the entity are performed in another context and will contain the correct value from the database (Kulkarni, Lifetime of a LINQ to SQL DataContext, 2008).&lt;B&gt;&lt;/B&gt;&lt;/P&gt;
&lt;P&gt;&lt;B&gt;2. &lt;/B&gt;&lt;B&gt;Manually update the entity’s time stamps to their original values. &lt;/B&gt;After the conflict exception is caught and the entities in conflict are resolved, the entities that were also not in conflict must have their time stamp properties updated.&lt;B&gt;&lt;/B&gt;&lt;/P&gt;
&lt;H4&gt;&lt;A title=_Toc213640093 name=_Toc213640093&gt;&lt;/A&gt;Refreshing entities&lt;/H4&gt;
&lt;P&gt;LINQ to SQL offers a succinct means to refresh materialized entities, either singularly or in a collection; however, some behavioral anomalies were uncovered that lead to issues with the application—specifically issues with “deep refresh” or refresh of related entities:&lt;/P&gt;
&lt;P&gt;1. &lt;B&gt;The refresh method only works for objects that have already been materialized.&lt;/B&gt; If additional foreign keys have been added to the database they are not loaded on a refresh call--membership is fixed once the related entities are loaded (Kulkarni, LINQ to SQL Tips 6: How to refresh given DataContext won't stomp on your objects, 2008).&lt;/P&gt;
&lt;P&gt;&lt;B&gt;2. &lt;/B&gt;&lt;B&gt;To load additional foreign keys a new select statement must be issued. &lt;/B&gt;New entities are added to the collection during a new selection; however, existing entities are not updated due to LINQ to SQL object pooling. A refresh is required of the entities to ensure they are up to date (Kulkarni, LINQ to SQL Tips 9: Understanding DataContext's internal caching, 2008).&lt;B&gt;&lt;/B&gt;&lt;/P&gt;
&lt;P&gt;This became an issue in our application where we have a single entity that contains a dozen foreign key relationships. Performing a deep refresh (having refreshed all data from all related entities from the database) issues dozens of queries to the database (specifically it is the number of related entities multiplied by two).&lt;/P&gt;
&lt;H3&gt;&lt;A title=_Toc213640094 name=_Toc213640094&gt;&lt;/A&gt;Query Throughput and Scalability&lt;/H3&gt;
&lt;P&gt;Our application employs the use of several static queries to retrieve data in various portions of the application (examples: work in progress, recently completed work, etc.). Upon execution of the query the results are bound to a list where the user can interact with them. The fundamental issue we had was with large amounts of objects being materialized on query execution (greater than 500). The queries took large amounts of time to complete (due to materialization overhead) and either timed out or the clients ran out of memory. In instances where objects were successfully materialized the users would encounter out of memory errors due to a memory leak with the DataContext object after two to four hours of regular usage.&lt;/P&gt;
&lt;P&gt;To resolve this issue the application used stored procedures to return the required data quickly and bind to the list box for interaction, invoking object materialization when the user navigated to the item for interaction. The resulting read only list did not provide all of the rich interaction features the entities provided (such as updating data for multiple items in the list when it is updated in a detail screen), however, the resulting query performance was much more acceptable and netted a big usability gain. The issue with memory leaking still persisted but under normal usage conditions was not noticeable.&lt;/P&gt;
&lt;H3&gt;&lt;A title=_Toc213640095 name=_Toc213640095&gt;&lt;/A&gt;Concluding Remarks&lt;/H3&gt;
&lt;P&gt;LINQ to SQL provides the ability to expose database objects as they exist in the relational world as .NET objects without layers of abstraction. Providing an easy mechanism to expose LOB data at the cost of some performance, developers must focus on balancing materialized objects and their lifetimes. Our LOB tools were able to effectively accomplish this by minimizing the amount of tracked entities materialized by leveraging stored procedures for bulk data retrieval and LINQ to SQL for specific data edits resulting in a seamless experience to the end user. &lt;/P&gt;
&lt;H3&gt;&lt;A title=_Toc213640096 name=_Toc213640096&gt;&lt;/A&gt;Works Cited&lt;/H3&gt;
&lt;P&gt;Kulkarni, D. (2008, April 27). &lt;I&gt;Lifetime of a LINQ to SQL DataContext&lt;/I&gt;. Retrieved from Dinesh's Cyberstation: http://blogs.msdn.com/dinesh.kulkarni/archive/2008/04/27/lifetime-of-a-linq-to-sql-datacontext.aspx&lt;/P&gt;
&lt;P&gt;Kulkarni, D. (2008, May 23). &lt;I&gt;LINQ to SQL Tips 6: How to refresh given DataContext won't stomp on your objects&lt;/I&gt;. Retrieved from Dinesh's Cyberstation: http://blogs.msdn.com/dinesh.kulkarni/archive/2008/05/23/linq-to-sql-tips-6-how-to-refresh-given-datacontext-won-t-stomp-on-your-objects.aspx&lt;/P&gt;
&lt;P&gt;Kulkarni, D. (2008, July 1). &lt;I&gt;LINQ to SQL Tips 9: Understanding DataContext's internal caching&lt;/I&gt;. Retrieved from Dinesh's Cyberstation: http://blogs.msdn.com/dinesh.kulkarni/archive/2008/07/01/linq-to-sql-tips-9-understanding-datacontext-s-internal-caching.aspx&lt;/P&gt;
&lt;P&gt;Parra, S. (2008, June 2). &lt;I&gt;Feedback: Linq. Conflict resolving records with timestamps&lt;/I&gt;. Retrieved from Microsoft Connect: http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=348901&lt;/P&gt;
&lt;P&gt;Strahl, R. (2007, August 15). &lt;I&gt;LINQ to SQL and Disconnected Entities Follow-up&lt;/I&gt;. Retrieved December 7, 2007, from Rick Strahl's Web Log: &lt;A href="http://www.west-wind.com/weblog/posts/135659.aspx" mce_href="http://www.west-wind.com/weblog/posts/135659.aspx"&gt;http://www.west-wind.com/weblog/posts/135659.aspx&lt;/A&gt;&lt;/P&gt;&lt;SPAN class=technoratitag&gt;Technorati Tags: &lt;A title="Link to Technorati Tag category for LINQ" href="http://www.technorati.com/tag/LINQ" rel=tag target=_blank&gt;LINQ&lt;/A&gt;, &lt;A title="Link to Technorati Tag category for SQL" href="http://www.technorati.com/tag/SQL" rel=tag target=_blank&gt;SQL&lt;/A&gt;, &lt;A title="Link to Technorati Tag category for DATABASE" href="http://www.technorati.com/tag/DATABASE" rel=tag target=_blank&gt;DATABASE&lt;/A&gt;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN class=sociallinks&gt;Add to: | &lt;A href="http://technorati.com/faves?add=http%3A%2F%2Fblogs%2Emsdn%2Ecom%2Frimuri%2Farchive%2F2009%2F08%2F26%2Fbuilding%2Dline%2Dof%2Dbusiness%2Dapplications%2Dwith%2Dlinq%2Dto%2Dsql%2Easpx" target=_blank&gt;Technorati&lt;/A&gt; | &lt;A href="http://digg.com/submit?phase=2&amp;amp;url=http%3A%2F%2Fblogs%2Emsdn%2Ecom%2Frimuri%2Farchive%2F2009%2F08%2F26%2Fbuilding%2Dline%2Dof%2Dbusiness%2Dapplications%2Dwith%2Dlinq%2Dto%2Dsql%2Easpx" target=_blank&gt;Digg&lt;/A&gt; | &lt;A href="http://del.icio.us/post?url=http%3A%2F%2Fblogs%2Emsdn%2Ecom%2Frimuri%2Farchive%2F2009%2F08%2F26%2Fbuilding%2Dline%2Dof%2Dbusiness%2Dapplications%2Dwith%2Dlinq%2Dto%2Dsql%2Easpx;title=Building%20Line%20of%20Business%20Applications%20with%20LINQ%20to%20SQL" target=_blank&gt;del.icio.us&lt;/A&gt; | &lt;A href="http://reddit.com/submit?url=http%3A%2F%2Fblogs%2Emsdn%2Ecom%2Frimuri%2Farchive%2F2009%2F08%2F26%2Fbuilding%2Dline%2Dof%2Dbusiness%2Dapplications%2Dwith%2Dlinq%2Dto%2Dsql%2Easpx&amp;amp;title=Building%20Line%20of%20Business%20Applications%20with%20LINQ%20to%20SQL" target=_blank&gt;reddit&lt;/A&gt; | &lt;/SPAN&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9885575" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/rimuri/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/rimuri/archive/tags/LINQ+to+SQL+_2800_DLINQ_2900_/default.aspx">LINQ to SQL (DLINQ)</category></item><item><title>Influencing Executives</title><link>http://blogs.msdn.com/rimuri/archive/2009/06/17/influencing-executives.aspx</link><pubDate>Thu, 18 Jun 2009 01:03:40 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9770726</guid><dc:creator>Richard Murillo</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/rimuri/comments/9770726.aspx</comments><wfw:commentRss>http://blogs.msdn.com/rimuri/commentrss.aspx?PostID=9770726</wfw:commentRss><wfw:comment>http://blogs.msdn.com/rimuri/rsscomments.aspx?PostID=9770726</wfw:comment><description>&lt;p&gt;&lt;strong&gt;Preparing Your Idea&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;The first real step in preparing a proposal with a greater chance of success is finding a subject you’re passionate about. Even if you present all the data to support your idea, your lack of passion for the subject will give you the disadvantage when asking an executive to take a risk on you and your idea. Once you have that, you need to ensure you’re not duplicating effort occurring elsewhere in the industry or within your own company. Once you’re in the clear on that you must refine your idea to make it crisp.&lt;/p&gt;  &lt;p&gt;Executives take risks on people, make it count. Having clearly and concisely articulated your vision, the same must be done for the ROI associated with implementing your vision. Often ideas undertaking major changes are not specifically actionable (or at least cannot be easily explained and understood in 30 seconds), so they must be decomposed. In doing so the constraints of organization budget become less of a factor—individual actionable items can be accomplished in various stages to accomplish the larger vision. Additionally, if you’ve clearly explained the value of your vision, it is understood by the sponsor, and it is the right thing for the company to do, there is a greater chance you will get funding.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Making the Pitch&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;At this point you should be well prepared for your meeting. Ensure you can clearly articulate your vision in less than 30 seconds (elevator pitch) and remember to bring the passion. Data is optional, passion is not. It also good to note the clear separate between what you like to have and what is needed to be successful.&lt;/p&gt;  &lt;p&gt;If in the event your sponsor does not approve your proposal, don’t give up. In the meeting debrief, consider the following questions:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Is the vision clear? &lt;/li&gt;    &lt;li&gt;Is this really the right thing for the company? &lt;/li&gt;    &lt;li&gt;Has the distinction between what you would like and what you need been clearly made? &lt;/li&gt;    &lt;li&gt;Is there history of you not delivering results? &lt;/li&gt;    &lt;li&gt;Is the scope granular enough so it can be accomplished? &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Don’t give up. Iterate on your idea and your materials and try again. If your vision is clear and sufficient ROI present, your chances of getting approval are high.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Reporting Status and Delivering Results&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Once you have funding it is now important that you deliver regular status updates and deliver. You may find that your executive sponsor wishes to be involved in your project—indulge them. Let them feel your passion and excitement by being involved. However in any circumstance, ensure that when you deliver your status that it is done so clearly and often, typically being less than 1/2 page. It is also important that mistakes made during your project are surfaced quickly and that responsibility and remediation is clearly evident. Surfacing mistakes made can potentially save large amounts of time, effort, and money to other team members or organizations within your company and will be appreciated by your sponsor.&lt;/p&gt;  &lt;p&gt;It is also important to think of your project plan, and its artifacts, as results delivered for a “blue chip” company, even if yours is not. Blue chip results are based out of lean project plans, where results are consistent, of high quality, and are widely accepted. Much like companies of the same name, projects executed in this manner can weather changes in economic conditions and build reputations of stability and reliability.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9770726" width="1" height="1"&gt;</description></item><item><title>Easy String to Resource file refactoring</title><link>http://blogs.msdn.com/rimuri/archive/2009/02/10/easy-string-to-resource-file-refactoring.aspx</link><pubDate>Tue, 10 Feb 2009 21:47:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9411101</guid><dc:creator>Richard Murillo</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/rimuri/comments/9411101.aspx</comments><wfw:commentRss>http://blogs.msdn.com/rimuri/commentrss.aspx?PostID=9411101</wfw:commentRss><wfw:comment>http://blogs.msdn.com/rimuri/rsscomments.aspx?PostID=9411101</wfw:comment><description>&lt;P&gt;During the development of internal tools we often have to stop working on features and clean up after ourselves to ensure that strings and such are embedded in the appropriate resource files and not hard coded into our applications. This can be a very tedious and time consuming process. Luckily there is a refactor extension that makes this very easy.&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;EM&gt;Resource&amp;nbsp;Refactoring Tool&amp;nbsp;&lt;/EM&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;Resource Refactoring Tool provides developers an easy way to extract hard coded strings from the code to resource files. &lt;/EM&gt;&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;&lt;STRONG&gt;Features for Resource Refactoring Tool&lt;BR&gt;&lt;BR&gt;&lt;/STRONG&gt;Works with C#, VB.Net languages. Supports all project types that ships with Visual Studio 2005 including web sites and web application projects. &lt;/EM&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;EM&gt;A preview window to show changes. &lt;/EM&gt;
&lt;LI&gt;&lt;EM&gt;Finds other instances of the text being replaced in the project automatically. &lt;/EM&gt;
&lt;LI&gt;&lt;EM&gt;Lists existing resources by their similarity level to the text being replaced. &lt;/EM&gt;
&lt;LI&gt;&lt;EM&gt;Automatically replaces hard coded string with a reference to resource entry. &lt;/EM&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;More information at &lt;A href="http://www.codeplex.com/ResourceRefactoring"&gt;http://www.codeplex.com/ResourceRefactoring&lt;/A&gt;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9411101" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/rimuri/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/rimuri/archive/tags/Visual+Studio/default.aspx">Visual Studio</category></item><item><title>Utilizing memoization and Dijkstra’s Fibonacci algorithm to compute large values</title><link>http://blogs.msdn.com/rimuri/archive/2008/10/15/utilizing-memoization-and-dijkstra-s-fibonacci-algorithm-to-compute-large-values.aspx</link><pubDate>Wed, 15 Oct 2008 21:49:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9000879</guid><dc:creator>Richard Murillo</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/rimuri/comments/9000879.aspx</comments><wfw:commentRss>http://blogs.msdn.com/rimuri/commentrss.aspx?PostID=9000879</wfw:commentRss><wfw:comment>http://blogs.msdn.com/rimuri/rsscomments.aspx?PostID=9000879</wfw:comment><description>&lt;p&gt;More of an acute fascination than anything else I expanded &lt;a href="http://blogs.msdn.com/rimuri/archive/2008/10/15/significantly-speeding-up-computations-with-smart-predicates.aspx" mce_href="http://blogs.msdn.com/rimuri/archive/2008/10/15/significantly-speeding-up-computations-with-smart-predicates.aspx"&gt;my use of memoization for computation&lt;/a&gt; to use a more efficient means of calculating Fibonacci sequences for values of n greater than 40 (previous Fibonacci example takes several minutes to compute value at 45 and is fairly unusable beyond that). To perform the computing of Fibonacci I utilized Dijkstra's algoritm for graph search pathing (algorithm details can be found in &lt;a href="http://www.cs.utexas.edu/users/EWD/ewd06xx/EWD654.PDF" mce_href="http://www.cs.utexas.edu/users/EWD/ewd06xx/EWD654.PDF"&gt;EWD654 &amp;quot;In honor of Fibonacci&amp;quot;&lt;/a&gt;). &lt;/p&gt;  &lt;p&gt;Dijkstra's algorithm for Fibonacci: &lt;/p&gt;  &lt;pre&gt;D(2n) = (2D(n-1) + D(n))D(n)
D(2n-1) = D(n-1)&lt;sup&gt;2&lt;/sup&gt; + D(n)&lt;sup&gt;2&lt;/sup&gt; &lt;/pre&gt;

&lt;p&gt;This algorithm in C#: &lt;/p&gt;

&lt;div id="codeSnippetWrapper"&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" id="codeSnippet"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; Func Dijkstra = n =&amp;gt;&lt;br /&gt;{&lt;br /&gt;     &lt;span style="color: #0000ff"&gt;if&lt;/span&gt;( n &amp;lt; 2 )&lt;br /&gt;          &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; n;&lt;br /&gt;&lt;br /&gt;     &lt;span style="color: #0000ff"&gt;double&lt;/span&gt; half = ( n % 2 == 0 ) ? n / 2 : ( n / 2 ) + 1;&lt;br /&gt;&lt;br /&gt;     &lt;span style="color: #0000ff"&gt;double&lt;/span&gt; p1 = Dijkstra( half );&lt;br /&gt;     &lt;span style="color: #0000ff"&gt;double&lt;/span&gt; p2 = Dijkstra( half - 1 );&lt;br /&gt;     &lt;span style="color: #0000ff"&gt;double&lt;/span&gt; result = &lt;span style="color: #0000ff"&gt;default&lt;/span&gt;( &lt;span style="color: #0000ff"&gt;double&lt;/span&gt; );&lt;br /&gt;&lt;br /&gt;     &lt;span style="color: #0000ff"&gt;if&lt;/span&gt;( n % 2 == 0 )&lt;br /&gt;          result = ( 2 * p2 + p1 ) * p1;&lt;br /&gt;     &lt;span style="color: #0000ff"&gt;else&lt;/span&gt;&lt;br /&gt;          result = Math.Pow( p2, 2 ) + Math.Pow( p1, 2 );&lt;br /&gt;&lt;br /&gt;     &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; result;&lt;br /&gt;};&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&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;Utilizing the memoization technique the amount of computations performed drops significantly. To compute the value of 50 the following computations are performed: &lt;/p&gt;

&lt;p&gt;&lt;span style="font-family: courier new"&gt;F(50) = F(25) and F(24) &lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span style="font-family: courier new"&gt;F(25) and F(24) = F(13) and F(12) &lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span style="font-family: courier new"&gt;F(13) and F(12) = F(7) and F(6) &lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span style="font-family: courier new"&gt;F(7) and F(6) = F(4) and F(3); F(3) and F(2) &lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span style="font-family: courier new"&gt;F(4) and F(3) = F(2) and F(1) &lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span style="font-family: courier new"&gt;F(3) = F(2) and F(1) &lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span style="font-family: courier new"&gt;F(2) = F(1) and F(0) &lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span style="font-family: courier new"&gt;F(1) and F(0) are 1 and 0 &lt;/span&gt;&lt;/p&gt;

&lt;p&gt;Utilizing this technique the number of computations required is 14. At the cost of some space the computations become faster as the graph becomes denser.&lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:a9a584e8-715c-4bd2-82cf-c1a302a42680" class="wlWriterSmartContent"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/C%23" rel="tag"&gt;C#&lt;/a&gt;,&lt;a href="http://technorati.com/tags/code" rel="tag"&gt;code&lt;/a&gt;,&lt;a href="http://technorati.com/tags/tech" rel="tag"&gt;tech&lt;/a&gt;,&lt;a href="http://technorati.com/tags/software" rel="tag"&gt;software&lt;/a&gt;,&lt;a href="http://technorati.com/tags/algorithms" rel="tag"&gt;algorithms&lt;/a&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9000879" width="1" height="1"&gt;</description></item><item><title>Significantly speeding up computations with smart predicates</title><link>http://blogs.msdn.com/rimuri/archive/2008/10/15/significantly-speeding-up-computations-with-smart-predicates.aspx</link><pubDate>Wed, 15 Oct 2008 21:13:48 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9000847</guid><dc:creator>Richard Murillo</dc:creator><slash:comments>3</slash:comments><comments>http://blogs.msdn.com/rimuri/comments/9000847.aspx</comments><wfw:commentRss>http://blogs.msdn.com/rimuri/commentrss.aspx?PostID=9000847</wfw:commentRss><wfw:comment>http://blogs.msdn.com/rimuri/rsscomments.aspx?PostID=9000847</wfw:comment><description>&lt;p&gt;There is a technique that allows optimization of repeated calculation results for a set of inputs called &lt;a href="http://en.wikipedia.org/wiki/Memoization"&gt;memoization&lt;/a&gt;. This technique is particularly helpful when working with numeric computations, pathing, such as for tree searches, etc. where the time taken to traverse the result set is expediential. What's more interesting is that the technique is applied on top of the System.Func object allowing for transparent optimization of those delegate types. Here is the method that I use to perform the optimization. &lt;/p&gt;  &lt;div id="codeSnippetWrapper"&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" id="codeSnippet"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; SystemMemoizationExtension &lt;br /&gt;{ &lt;br /&gt;    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;object&lt;/span&gt; lockObject = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #0000ff"&gt;object&lt;/span&gt;(); &lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; Func Memoize( &lt;span style="color: #0000ff"&gt;this&lt;/span&gt; Func func ) &lt;br /&gt;    { &lt;br /&gt;        Dictionary t = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Dictionary(); &lt;br /&gt;        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; n =&amp;gt; &lt;br /&gt;        { &lt;br /&gt;            &lt;span style="color: #0000ff"&gt;if&lt;/span&gt;( !t.ContainsKey( n ) ) &lt;br /&gt;            { &lt;br /&gt;                &lt;span style="color: #0000ff"&gt;lock&lt;/span&gt;( lockObject ) &lt;br /&gt;                { &lt;br /&gt;                    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt;( !t.ContainsKey( n ) ) &lt;br /&gt;                    { &lt;br /&gt;                        var result = func( n ); &lt;br /&gt;                        t.Add( n, result ); &lt;br /&gt;                    } &lt;br /&gt;                } &lt;br /&gt;            } &lt;br /&gt;            &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; t[ n ]; &lt;br /&gt;        }; &lt;br /&gt;    } &lt;br /&gt;} &lt;/pre&gt;

  &lt;br /&gt;&lt;/div&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;To utilize the method simply assign the result of the Memoize method back to your delegate as shown in the example below. &lt;/p&gt;

&lt;div id="codeSnippetWrapper"&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" id="codeSnippet"&gt;Func&amp;lt;&lt;span style="color: #0000ff"&gt;int&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;int&lt;/span&gt;&amp;gt; Fibonacci = &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;; &lt;br /&gt;&lt;span style="color: #008000"&gt;//Recursive Fibonacci algorithm&lt;/span&gt;&lt;br /&gt;Fibonacci = n &amp;gt;=n &amp;lt;= 1 ? n : Fibonacci(n – 1) + Fibonacci(n-2); &lt;br /&gt;&lt;span style="color: #008000"&gt;//Optimize lookups&lt;/span&gt;&lt;br /&gt;Fibonacci = Fibonacci.Memoize(); &lt;/pre&gt;

  &lt;br /&gt;&lt;/div&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;While this is an overly simplistic example of recursion optimization you can see that by calling the code once then again using the same input that a dramatic improvement is made performing the computation (an input for F(n) where n = 42 takes several seconds to compute, while the subsequent call takes sub seconds). The technique itself is useful for reducing the traversal time for any top-down parsing.&lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:4e1ceebd-1b99-41d7-8006-d619f87654fe" class="wlWriterSmartContent"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/C%23" rel="tag"&gt;C#&lt;/a&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9000847" width="1" height="1"&gt;</description></item><item><title>Extensions I found useful while developing with WPF and LINQ to SQL</title><link>http://blogs.msdn.com/rimuri/archive/2008/10/15/extensions-i-found-useful-while-developing-with-wpf-and-linq-to-sql.aspx</link><pubDate>Wed, 15 Oct 2008 20:54:11 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9000819</guid><dc:creator>Richard Murillo</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/rimuri/comments/9000819.aspx</comments><wfw:commentRss>http://blogs.msdn.com/rimuri/commentrss.aspx?PostID=9000819</wfw:commentRss><wfw:comment>http://blogs.msdn.com/rimuri/rsscomments.aspx?PostID=9000819</wfw:comment><description>&lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;When I observe developers writing solutions using LINQ to SQL or Entity Framework, I see a number of conversions occurring time and time again. Below are some of the more trivial utility method extensions I used when developing solutions based on LINQ to SQL and WPF—simple as they are I found them useful in a variety of situations. &lt;/p&gt;  &lt;p&gt;Extension to remove data from a collection using a predicate. &lt;/p&gt;  &lt;div id="codeSnippetWrapper"&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" id="codeSnippet"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; Remove&amp;lt;T&amp;gt;( &lt;span style="color: #0000ff"&gt;this&lt;/span&gt; ICollection&amp;lt;T&amp;gt; data, Func&amp;lt;T, &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt;&amp;gt; predicate )&lt;br /&gt;{&lt;br /&gt;     &lt;span style="color: #0000ff"&gt;if&lt;/span&gt;( predicate == &lt;span style="color: #0000ff"&gt;null&lt;/span&gt; ) &lt;br /&gt;     {&lt;br /&gt;          data.Clear(); &lt;br /&gt;     } &lt;br /&gt;     &lt;span style="color: #0000ff"&gt;else&lt;/span&gt; &lt;br /&gt;     { &lt;br /&gt;         &lt;span style="color: #0000ff"&gt;foreach&lt;/span&gt;( T item &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; data.Where( predicate )) &lt;br /&gt;         { &lt;br /&gt;               data.Remove( item ); &lt;br /&gt;         } &lt;br /&gt;     } &lt;br /&gt;} &lt;/pre&gt;

  &lt;br /&gt;&lt;/div&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;&lt;span style="font-family: courier new"&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;Converting an enumerable to an ObservableCollection for data binding &lt;/p&gt;

&lt;div id="codeSnippetWrapper"&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" id="codeSnippet"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; ObservableCollection&amp;lt;T&amp;gt; ToObservableCollection&amp;lt;T&amp;gt;( &lt;span style="color: #0000ff"&gt;this&lt;/span&gt; IEnumerable&amp;lt;T&amp;gt; collection ) &lt;br /&gt;{ &lt;br /&gt;    List&amp;lt;T&amp;gt; list = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; List&amp;lt;T&amp;gt;( collection.Count() ); &lt;br /&gt;    &lt;span style="color: #0000ff"&gt;using&lt;/span&gt;( IEnumerator&amp;lt;T&amp;gt; enumerator = collection.GetEnumerator() ) &lt;br /&gt;    { &lt;br /&gt;        &lt;span style="color: #0000ff"&gt;while&lt;/span&gt;( enumerator.MoveNext() ) &lt;br /&gt;        { &lt;br /&gt;            list.Add( enumerator.Current ); &lt;br /&gt;        } &lt;br /&gt;    } &lt;br /&gt;    &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; ObservableCollection&amp;lt;T&amp;gt;( list ); &lt;br /&gt;} &lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;&lt;span style="font-family: courier new"&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;The same but for a list &lt;/p&gt;

&lt;div id="codeSnippetWrapper"&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" id="codeSnippet"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; ObservableCollection&amp;lt;T&amp;gt; ToObservableCollection&amp;lt;T&amp;gt;( &lt;span style="color: #0000ff"&gt;this&lt;/span&gt; List&amp;lt;T&amp;gt; collection ) &lt;br /&gt;{ &lt;br /&gt;    &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; ObservableCollection&amp;lt;T&amp;gt;( collection ); &lt;br /&gt;}&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;&lt;span style="font-family: courier new"&gt;&lt;/span&gt;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9000819" width="1" height="1"&gt;</description></item><item><title>Software development outsourcing and client proximity</title><link>http://blogs.msdn.com/rimuri/archive/2008/03/08/software-development-outsourcing-and-client-proximity.aspx</link><pubDate>Sat, 08 Mar 2008 22:09:13 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8114322</guid><dc:creator>Richard Murillo</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/rimuri/comments/8114322.aspx</comments><wfw:commentRss>http://blogs.msdn.com/rimuri/commentrss.aspx?PostID=8114322</wfw:commentRss><wfw:comment>http://blogs.msdn.com/rimuri/rsscomments.aspx?PostID=8114322</wfw:comment><description>&lt;p&gt;I had a recent comment come in that I wanted to share:
&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;I was wondering what your take was on Consulting firms. Although it is not offshore outsourcing, in some sense, it is still outsourcing their projects to firms. I totally agree with you regarding the lack of communication and planning to execute and deliver projects when attempting to have someone work on a project 2000 miles away from you.
&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;The short of it is there is still risk in outsourcing no matter the proximity, however, I believe that there are three key tenets that facilitate failure in the situation:
&lt;/p&gt;&lt;ul style="margin-left: 54pt"&gt;&lt;li&gt;Spoken and written language comprehension
&lt;/li&gt;&lt;li&gt;Cultural awareness and differences 
&lt;/li&gt;&lt;li&gt;location, location, location
&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Communication plays a fundamental role in project success, whether it is with the local project team, virtual team members, or external parties. I believe the biggest challenges we face with traditional overseas outsourcing revolves around this, however I have experienced similar challenges with outsourced work with American vendors for different reasons all together, so there's a project risk either way.
&lt;/p&gt;&lt;p&gt;Fundamentally it comes down to a risk management decision for the client. I have found that groups and companies that do not have their own crisp corporate governance, operational and infrastructure policies are more often than not unsuccessful in outsourcing (root cause is uncontrolled chaos undermining communication plans and data management policies). In a vendor/client model there are a few things we have exercised to be successful: emphasis on information security, a clear and well understood communication protocol, and frequent audits to ensure policy compliance. Above all of that there's also the associated business risk of the outsourcing deal that needs to be managed up front. In either "near" or "far" outsourcing, the recognition of a failing deal is pivotal to shifting risk back on to the vendor.
&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8114322" width="1" height="1"&gt;</description></item><item><title>Visual Studio 2008 Released</title><link>http://blogs.msdn.com/rimuri/archive/2007/11/26/visual-studio-2008-released.aspx</link><pubDate>Mon, 26 Nov 2007 23:05:37 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:6534091</guid><dc:creator>Richard Murillo</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/rimuri/comments/6534091.aspx</comments><wfw:commentRss>http://blogs.msdn.com/rimuri/commentrss.aspx?PostID=6534091</wfw:commentRss><wfw:comment>http://blogs.msdn.com/rimuri/rsscomments.aspx?PostID=6534091</wfw:comment><description>&lt;p&gt;After months of waiting, I can finally say that Visual Studio 2008 was released last week. There are hundreds of new features, language enhancements, and technology integrations in this version. To help you get your head around what is new in Visual Studio 2008 and .NET Framework 3.5, &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=8bdaa836-0bba-4393-94db-6c3c4a0c98a1&amp;amp;DisplayLang=en"&gt;get the training kit from Microsoft download center&lt;/a&gt;. 
&lt;/p&gt;&lt;p&gt;Some new features that I am excited about:
&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Visual Studio performance improvements
&lt;/li&gt;&lt;li&gt;AJAX integration with javascript intellisense
&lt;/li&gt;&lt;li&gt;Cider integration (WPF visualizer)
&lt;/li&gt;&lt;li&gt;Multi-core builds
&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.microsoft.com/windowsserver2008/default.mspx"&gt;Windows Server 2008&lt;/a&gt; / &lt;a href="http://www.microsoft.com/sql/2008/default.mspx"&gt;SQL Server 2008&lt;/a&gt; support (TFS)
&lt;/li&gt;&lt;li&gt;Vista UAC compliance
&lt;/li&gt;&lt;li&gt;Continuous integration
&lt;/li&gt;&lt;li&gt;Web Access
&lt;/li&gt;&lt;li&gt;Integration of Database Edition (VSTS SKU)
&lt;/li&gt;&lt;li&gt;T-SQL Static code analysis
&lt;/li&gt;&lt;li&gt;SQL Dependency tree visualization
&lt;/li&gt;&lt;li&gt;Schema reporting for documentation
&lt;/li&gt;&lt;li&gt;T-SQL refactoring
&lt;/li&gt;&lt;li&gt;New designers for SOA scenarios
&lt;/li&gt;&lt;li&gt;Hotpathing (tell me where perf in my application sucks)
&lt;/li&gt;&lt;li&gt;LINQ&lt;/li&gt;&lt;/ul&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=6534091" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/rimuri/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/rimuri/archive/tags/Visual+Studio/default.aspx">Visual Studio</category><category domain="http://blogs.msdn.com/rimuri/archive/tags/LINQ+to+SQL+_2800_DLINQ_2900_/default.aspx">LINQ to SQL (DLINQ)</category></item><item><title>Why moving work offshore fails </title><link>http://blogs.msdn.com/rimuri/archive/2007/04/20/why-moving-work-offshore-fails.aspx</link><pubDate>Fri, 20 Apr 2007 19:19:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:2208855</guid><dc:creator>Richard Murillo</dc:creator><slash:comments>4</slash:comments><comments>http://blogs.msdn.com/rimuri/comments/2208855.aspx</comments><wfw:commentRss>http://blogs.msdn.com/rimuri/commentrss.aspx?PostID=2208855</wfw:commentRss><wfw:comment>http://blogs.msdn.com/rimuri/rsscomments.aspx?PostID=2208855</wfw:comment><description>&lt;P&gt;Not to say that all offshore projects fail, I have both been a contributor and leader in projects that have been a great success and those that have been complete failures. Each project had its own reasons for failing and&amp;nbsp;were defined by the business (e.g. why are you sending it offshore to begin with) that typically include&amp;nbsp;cost savings, quality, increased turnaround in deliverables,&amp;nbsp;and customer satisfaction--all of which&amp;nbsp;are key drivers for moving work offshore, but in doing so there are key areas your business must pay close attention to. &lt;/P&gt;
&lt;P&gt;According to Gartner, businesses will spend more than $50 billion USD on offshore and "near-shore" outsourcing by 2007 and many projects will fail because of poor planning. Gartner also maintains that there are benefits achieved by those businesses that successfully outsource their non-core processes, however, rewards will not be instant. &lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Reasons for Failure &lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Often times, the effort and time involved in communicating with offshore team members and maintaining that relationship is underestimated. In my experiences with offshore teams to date, there has often been a lack of key items to complete awarded work effectively (like infrastructure, soft skills, planning). Additionally, coordinating between the teams requires longer hours, detailed planning, and cultural training—all of which are more expensive when working with offshore than with your own staff and can, as I have observed here, lead to lower morale and reduced deliverable output. Gartner also observes that lack of productivity in the offshore is also an issue for several reasons including high staff turnover and skill levels, especially in highly competitive markets such as Bangalore and Hyderabad, India. &lt;/P&gt;
&lt;P&gt;Much like the dot com days, new programmers coming into the field of work are inexperienced, attaining only the necessary core skills for them to receive a job in this field and often struggle with ambiguities in specification or shifting directives. As such, the teams typically do not operate with clear processes and depend on the competence and heroics of those more experienced and not on the use of proven processes. In spite of the chaos, these teams often produce usable work products; however, they frequently exceed the budget and schedule. More often than not these teams over commit, abandon any established process in times of chaos, and may not be able to repeat past successes again. &lt;/P&gt;
&lt;P&gt;What's more, senior executives are not involved to keep strategy on track and morale high—they are only in the picture when a significant escalation occurs or to sign a new deal. As I mentioned in my &lt;A class="" href="http://blogs.msdn.com/rimuri/archive/2007/04/03/outsourced-projects-on-using-visual-studio-team-system.aspx" target=_blank mce_href="http://blogs.msdn.com/rimuri/archive/2007/04/03/outsourced-projects-on-using-visual-studio-team-system.aspx"&gt;previous entry&lt;/A&gt;, in order for an offshore deal to succeed there needs to be a good level of communication between all parties. Requirements, goals, and expectations have to be defined clearly and in detail. Your onshore managers need to explain to the coordinating staff why the work has been sent offshore and what benefits are expected. &lt;/P&gt;
&lt;P&gt;More often than not, the cultural differences will come into play creating havoc for the project; classic incarnations of this include not questioning authority and just pressing forward by the offshore team. All too many times do we find out late that guidance or requirements had been ignored for cross cutting to please the schedule rather than announcing a slip. &lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;How can Visual Studio Team System help? &lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Gartner advises companies that plan on offshoring work to figure out their IT process maturity and identify gaps in your process. As previously mentioned, it is important to set all expectations clearly up front with your vendor. When using Visual Studio 2005 with Team Foundation Server, several mechanisms out of box enable teams to work effectively in these environments: &lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Process: &lt;/STRONG&gt;out of the box, Visual Studio Team Foundation server includes &lt;A href="http://msdn2.microsoft.com/en-us/teamsystem/aa718802.aspx" mce_href="http://msdn2.microsoft.com/en-us/teamsystem/aa718802.aspx"&gt;MSF for CMMI Process Improvement Level 3&lt;/A&gt; and &lt;A href="http://msdn2.microsoft.com/en-us/teamsystem/aa718801.aspx" mce_href="http://msdn2.microsoft.com/en-us/teamsystem/aa718801.aspx"&gt;MSF for Agile Development&lt;/A&gt; work item templates. By utilizing the templates and the process behind them, teams can effectively work across physical boundaries with increased confidence and transparency, allowing software development activities to be predictable and success repeatable.&lt;STRONG&gt; &lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Communication:&lt;/STRONG&gt; Visual Studio Team System facilitates the transparency between individuals and teams with work items, a shared team portal, integrated change management, and a common data repository. The availability of information, and insight into an individual's progress, creates a more unified work environment regardless of physical location. Project managers can stay informed on an individual's progress without having to visit each individual—having real time information about each individual's work and their progress allows project managers to create precise schedules and report more accurately to management&lt;STRONG&gt; &lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Productivity:&lt;/STRONG&gt; utilizing the common repository, managers and leads can answer common questions such as: What's in the current build that QA can test today; are requirements being met; are my teams adhereing to quality standards; is the product ready. Further, it provides the single team portal for integrating source code, issue tracking, project plans, vision statements and others that are critical assets to a project team.&lt;/LI&gt;&lt;/UL&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=2208855" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/rimuri/archive/tags/Team+Foundation+Server/default.aspx">Team Foundation Server</category><category domain="http://blogs.msdn.com/rimuri/archive/tags/Visual+Studio/default.aspx">Visual Studio</category></item><item><title>Outsourced Projects using Visual Studio Team System</title><link>http://blogs.msdn.com/rimuri/archive/2007/04/03/outsourced-projects-on-using-visual-studio-team-system.aspx</link><pubDate>Tue, 03 Apr 2007 23:59:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:2020998</guid><dc:creator>Richard Murillo</dc:creator><slash:comments>3</slash:comments><comments>http://blogs.msdn.com/rimuri/comments/2020998.aspx</comments><wfw:commentRss>http://blogs.msdn.com/rimuri/commentrss.aspx?PostID=2020998</wfw:commentRss><wfw:comment>http://blogs.msdn.com/rimuri/rsscomments.aspx?PostID=2020998</wfw:comment><description>&lt;P&gt;Having been included in two separate teams where our outsourced projects don't go as well as expected I cannot help but to take a step back and ask why things are consistently failing with separate teams, and separate organizations. &lt;/P&gt;
&lt;P&gt;The commonalities in both projects were fixed-bid (i.e. fixed price, features and time) using a modified waterfall model (to account for geographic locations). I know—you say the waterfall model doesn't work. Be that as it may organizations revert to this model and are thus handicapped; unable to make adjustments to the changing business and unable to make definitive decisions on how to improve their process, but more on that later. Other commonalities included high level and low level designs, unit test cases, test cases, etc. &lt;/P&gt;
&lt;P&gt;I have heard that groups similar to mine are having great success with outsourced projects, and I myself have also been involved with projects that were executed to great success, however I assert that for us there are areas of improvement. At a high level, I can sum it up in one word: process. &lt;/P&gt;
&lt;P&gt;Where have my two projects failed? IMHO it is in the analysis of the requirements. The requirements had the vendors pegged implementing features on product technologies they were unfamiliar with—some churn in requirements and with new technology. Traditionally engineering teams would perform proof of concepts and experiments to validate design, and clickable prototypes to share with customers to stabilize requirements (business and technical). While some of that was done here, I still see where it could have been improved. In both instances, we started with a solid vendor relationship that quickly begins to fall apart due to lack of trust. IMHO the biggest areas we are lacking are: &lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Trust between teams &lt;/LI&gt;
&lt;LI&gt;High &lt;A href="http://en.wikipedia.org/wiki/Signal-to-noise_ratio" mce_href="http://en.wikipedia.org/wiki/Signal-to-noise_ratio"&gt;SNR&lt;/A&gt; in communication (i.e. direct, candid communications on issues, risk and status) &lt;/LI&gt;
&lt;LI&gt;Close coordination between said teams &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;IMHO in both projects are considered high risk when examining the vendor skill set, staffing model, and experience with projects of this complexity. In most situations you can apply the Parento principle (AKA 80-20 rule) where 80% of staff is offshore while 20% is onsite for R&amp;amp;D phases, moving to a 90-10 planned &lt;A href="http://c2.com/cgi/wiki/wiki?HistoryOfIterative" mce_href="http://c2.com/cgi/wiki/wiki?HistoryOfIterative"&gt;iterative&lt;/A&gt; model for build and less onsite still for stabilization. &lt;/P&gt;
&lt;P&gt;In both projects the offshore team encountered additional issues during implementation that require workarounds for resolution, R&amp;amp;D, or a complete shift in approach. On both projects we tried to mitigate risk by having frequent check-ins with the offshore team and checking progress on a tight basis (one was almost daily, the other bi-weekly). Alas when significant and unexpected delays arose the relationship fell to pieces and in response we put in-house staff on the project to sure it up and get it going in the right direction. &lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Lessons Learned &lt;/STRONG&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Complete as many iterations as you can:&lt;/STRONG&gt; That is, don't disrupt forward progress on the project for the sake of getting a work product from the team, but do get deliverables as often as it makes sense. Some of our projects get some weekly, others monthly. &lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Use collaborative tools to increase confidence in deliverables: &lt;/STRONG&gt;Your in-house staff does not have to wait until the end of the formal delivery cycle to perform review or check in with the offshore team. Utilize tools like LiveMeeting Net Meeting, Windows Live Messenger, etc. to increase collaboration&lt;STRONG&gt; &lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Code review, code review, code review: &lt;/STRONG&gt;DO NOT UNDERESTIMATE THIS. A majority of issues we found on one project were found in code review by in-house staff familiar with the business rules. In both projects the adherence to offshore code reviews prior to sending to our in-house staff was not maintained, resulting in many bugs raised later in the cycles. In the reviews we took code that was a representative sample (chosen at random, but was a deep slice) and did a review. Additionally we looked at key strategic areas for performance bottlenecks and security to ensure code conventions, standards, and requirements were being met&lt;STRONG&gt; &lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Integrate as frequently as possible: &lt;/STRONG&gt;Our teams use branches to logically separate the project or feature into areas for work. As a matter of practice, the more frequently these branches can be integrated the faster you can identify and resolve defects.&lt;STRONG&gt; &lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Where possible, leverage frameworks:&lt;/STRONG&gt; Use application blocks (&lt;A href="http://www.codeplex.com/entlib" mce_href="http://www.codeplex.com/entlib"&gt;Enterprise Library&lt;/A&gt;), &lt;A href="http://www.codeplex.com/websf/Wiki/View.aspx?title=Guidance%20Automation%20Overview&amp;amp;referringTitle=Home" mce_href="http://www.codeplex.com/websf/Wiki/View.aspx?title=Guidance%20Automation%20Overview&amp;amp;referringTitle=Home"&gt;Guidance Automation&lt;/A&gt; (&lt;A href="http://www.codeplex.com/websf" mce_href="http://www.codeplex.com/websf"&gt;Web Client Software Factory&lt;/A&gt;, &lt;A href="http://www.codeplex.com/smartclient" mce_href="http://www.codeplex.com/smartclient"&gt;Smart Client Software Factory&lt;/A&gt;) to solve common problems. Where possible, create your own frameworks and reuse them on projects to reduce the amount of custom code required to be written, which decreases development time and improves quality.&lt;STRONG&gt; &lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Use Design Patterns:&lt;/STRONG&gt; These patterns illustrate common ways to solve problems. Being standard, they can convey meaning across geographical boundaries. Further, by implementing patterns maintenance complexity is reduced and documentation and clarity is improved. A different vendor in a different country, maybe even in-house staff, may need to understand and modify the code—using a proven design allows ramp up to easily occur.&lt;STRONG&gt; &lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Use useful metrics to measure quality and progress: &lt;/STRONG&gt;Build metrics into SLAs and look at meaningful metrics, such as defect density, bug reactivations, code churn, code coverage (unit test or otherwise), project velocity, etc. &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;&lt;STRONG&gt;Leveraging Visual Studio Team System &lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;I have found that VSTS handles the needs of geographically dispersed development teams (and their inherent challenges) in a variety of ways: &lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;"Better" communication and coordination: &lt;/STRONG&gt;Team Foundation Server provides the ability to track work items (tasks, bugs, issues, requirements, risks, change requests) in addition to source code and documentation. The architecture, utilizing web services and cache servers, is optimized for distributed teams working over slow or unreliable connections. The product also allows for customizable notification of events to give you the clarity you need from the projects and help improve onsite/offshore communications &lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;"Better" status reports:&lt;/STRONG&gt; Coupled with the data warehouse maintaining statistics and work item history, reports can be generated to give you insight in to some of the metrics I mentioned above. The platform is also extensible, utilizing SQL Analysis Services (SSAS) and SQL Server Reporting Services (SSRS) to allow team members to gather information with various levels of granularity. &lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;"Better" code quality:&lt;/STRONG&gt; the product also includes a unit testing framework that works with the centralized build and reporting portions to give indications of code churn, unit test coverage, and pass rates. Check in policies can be configured to check if the code compiles, run static code analysis, even run selected tests &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Each one of these allow the onsite team to ensure compliance with corporate standards and gain trust in confidence in the offshore team's ability to deliver a quality, stable product.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=2020998" width="1" height="1"&gt;</description></item><item><title>Team Foundation Server Power Tools (tfpt) 1.2 Released</title><link>http://blogs.msdn.com/rimuri/archive/2007/02/21/team-foundation-server-power-tools-tfpt-1-2-released.aspx</link><pubDate>Wed, 21 Feb 2007 22:49:12 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:1736965</guid><dc:creator>Richard Murillo</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/rimuri/comments/1736965.aspx</comments><wfw:commentRss>http://blogs.msdn.com/rimuri/commentrss.aspx?PostID=1736965</wfw:commentRss><wfw:comment>http://blogs.msdn.com/rimuri/rsscomments.aspx?PostID=1736965</wfw:comment><description>&lt;p&gt;Today the Team Foundation Server team announced the release of version 1.2 of Team Foundation Power Tools (formally known as Power Toys). What are the Power Toys you say? They're extra functionality delivered out of band for Team Foundation Server including some really useful stuff (get changes for changeset, consolidated annotation of a file, command line history, and rollback to name a few).
&lt;/p&gt;&lt;p&gt;In the latest release they have included support for Windows Vista (woo-hoo!) and several new tools:
&lt;/p&gt;&lt;p style="margin-left: 18pt"&gt;&lt;em&gt;[from announcement]
&lt;/em&gt;&lt;/p&gt;&lt;ul style="margin-left: 54pt"&gt;&lt;li&gt;&lt;em&gt;&lt;strong&gt;Workspace Command (tfpt.exe) &lt;/strong&gt;- Use the &lt;strong&gt;workspace&lt;/strong&gt; command for additional workspace operations not supported in the currently shipping Team Foundation Server command-line tool (&lt;strong&gt;tf.exe&lt;/strong&gt;).
&lt;/em&gt;&lt;/li&gt;&lt;li&gt;&lt;em&gt;&lt;strong&gt;Treeclean Command&lt;/strong&gt; - Use the &lt;strong&gt;treeclean&lt;/strong&gt; command to see and optionally delete files in the current directory and all subdirectories that are not under version control.
&lt;/em&gt;&lt;/li&gt;&lt;li&gt;&lt;em&gt;&lt;strong&gt;Process Template Editor&lt;/strong&gt; - A tool that provides a user interface for authoring work item types and some of the associated process template components.
&lt;/em&gt;&lt;/li&gt;&lt;li&gt;&lt;em&gt;&lt;strong&gt;Check-in Policy Pack&lt;/strong&gt; - A set of custom policies that address often expressed customer needs. For example, the &lt;strong&gt;Custom Path Policy&lt;/strong&gt; allows you to filter the specific items upon which another policy acts.
&lt;/em&gt;&lt;/li&gt;&lt;li&gt;&lt;em&gt;&lt;strong&gt;Build Test Tools Task&lt;/strong&gt; - An MSBuild task that allows you to run unit tests by specifying the DLLs  or a file name pattern in the TfsBuild.proj file instead of using .vsmdi files to specify which tests to run.&lt;span style="font-family:Times New Roman; font-size:7pt"&gt;
				&lt;/span&gt;&lt;/em&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;One thing that I am very excited for is the new path policy (included in the Check-In Policy Pack). This allows policies to be applied to specific paths in team foundation server (i.e. don't check for valid unit tests on a directory with 3&lt;sup&gt;rd&lt;/sup&gt; party source code). The other policy I'm excited for is the work item query policy—my project teams have several builds operating concurrently within the same team project and sometimes a private build is executed and picks up work items and associations not belonging to it specifically creating false relationships and throwing off some of our reporting.
&lt;/p&gt;&lt;p&gt;To download version 1.2, go to the Microsoft Download center at &lt;a href="http://www.microsoft.com/downloads/details.aspx?familyid=7324c3db-658d-441b-8522-689c557d0a79&amp;amp;displaylang=en"&gt;http://www.microsoft.com/downloads/details.aspx?familyid=7324c3db-658d-441b-8522-689c557d0a79&amp;amp;displaylang=en&lt;/a&gt; Help for the new tools can be found on the TFPT Forums at &lt;a href="http://forums.microsoft.com/MSDN/ShowForum.aspx?ForumID=930&amp;amp;SiteID=1"&gt;http://forums.microsoft.com/MSDN/ShowForum.aspx?ForumID=930&amp;amp;SiteID=1&lt;/a&gt;
	&lt;/p&gt;&lt;p&gt;Additional information on the tools in depth can be found on &lt;a href="http://blogs.msdn.com/ukvsts/archive/2007/02/21/i-ve-got-the-power-tools.aspx"&gt;Rich's Developer Tools Blog&lt;/a&gt;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=1736965" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/rimuri/archive/tags/Team+Foundation+Server/default.aspx">Team Foundation Server</category></item><item><title>Getting my Sandcastle Team Build targets file to work with Sandcastle September CTP</title><link>http://blogs.msdn.com/rimuri/archive/2006/10/31/getting-my-sandcastle-team-build-targets-file-to-work-with-sandcastle-september-ctp.aspx</link><pubDate>Tue, 31 Oct 2006 20:45:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:913459</guid><dc:creator>Richard Murillo</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/rimuri/comments/913459.aspx</comments><wfw:commentRss>http://blogs.msdn.com/rimuri/commentrss.aspx?PostID=913459</wfw:commentRss><wfw:comment>http://blogs.msdn.com/rimuri/rsscomments.aspx?PostID=913459</wfw:comment><description>&lt;P&gt;A few things before we get started: &lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;You will need the &lt;A href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/htmlhelp/html/hwMicrosoftHTMLHelpDownloads.asp" mce_href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/htmlhelp/html/hwMicrosoftHTMLHelpDownloads.asp"&gt;HTML Help Workshop installed&lt;/A&gt; &lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://www.microsoft.com/downloads/details.aspx?FamilyId=E82EA71D-DA89-42EE-A715-696E3A4873B2&amp;amp;displaylang=en" mce_href="http://www.microsoft.com/downloads/details.aspx?FamilyId=E82EA71D-DA89-42EE-A715-696E3A4873B2&amp;amp;displaylang=en"&gt;September CTP of Sandcastle&lt;/A&gt; &lt;/LI&gt;
&lt;LI&gt;My September CTP Sandcastle Targets File (attached)&lt;BR&gt;This file needs to be copied to your %programfiles%\MSBuild directory &lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;Next you will need to make some modifications to the standard configuration file (I am using the VS2005 style) &lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;Make a copy of %programfiles%\Sandcastle\Presentation\vs2005\configuration\sandcastle.config &lt;/LI&gt;
&lt;LI&gt;
&lt;DIV&gt;Change references of &lt;/DIV&gt;
&lt;OL&gt;
&lt;LI&gt;..\..\ to %programfiles%\sandcastle\ &lt;/LI&gt;
&lt;LI&gt;..\cpref_reflection to %programfiles%\sandcastle\examples\cpref_reflection &lt;/LI&gt;&lt;/OL&gt;&lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;Update your TFSBuild.proj to include the following: &lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;Add a new Import tag referencing the sandcastle targets file &lt;/LI&gt;
&lt;LI&gt;
&lt;DIV&gt;Add a new target called DocumentCLR&lt;BR&gt;&amp;lt;Target Name="DocumentCLR"&amp;gt;&lt;BR&gt;&amp;lt;CallTarget Targets="SandcastleDocument" ContinueOnError="false" /&amp;gt; &lt;BR&gt;&amp;lt;MakeDir Condition="!Exists('$(BinariesRoot)\Documentation')" Directories="$(BinariesRoot)\Documentation" ContinueOnError="false" /&amp;gt;&lt;BR&gt;&amp;lt;Copy SourceFiles="$(SandcastleWorkingDirectory)\Output\$(SandcastleDocumentationName).chm" DestinationFiles="$(BinariesRoot)\Documentation\$(SandcastleDocumentationName).chm" ContinueOnError="false"/&amp;gt;&lt;BR&gt;&amp;lt;/Target&amp;gt; &lt;/DIV&gt;&lt;/LI&gt;
&lt;LI&gt;Add an additional target that overrides the AfterCompile target&lt;BR&gt;&amp;lt;Target Name="AfterCompile"&amp;gt;&lt;BR&gt;&amp;lt;CallTarget RunEachTargetSeparately="true" Targets="DocumentCLR" ContinueOnError="false"/&amp;gt;&lt;BR&gt;&amp;lt;OnError ExecuteTargets=" OnBuildBreak;"/&amp;gt;&lt;BR&gt;&amp;lt;/Target&amp;gt; &lt;/LI&gt;
&lt;LI&gt;Update your TFSBuild.rsp file to include some configuration&lt;BR&gt;/p:SandcastleDocumentationName=NameOfYourCHM&lt;BR&gt;/p:SandcastleConfiguration="C:\Path_TO_MODIFIED_CONFIG\sandcastle.config"&lt;BR&gt;/p:SandcastleDocumentationOutput=$(BinariesRoot)\Documentation&lt;BR&gt;/p:SandcastleDependencies="%windir%\Microsoft.NET\Framework\v2.0.50727\*.dll,\\lcabuildvm01\3rdParty\Dependencies\*.dll,%windir%\assembly\GAC_MSIL\Microsoft.VisualStudio.QualityTools.UnitTestFramework\8.0.0.0__b03f5f7f11d50a3a\Microsoft.VisualStudio.QualityTools.UnitTestFramework.dll"&lt;BR&gt;/p:SandcastleHelpGeneration=CHM&lt;/LI&gt;&lt;/OL&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=913459" width="1" height="1"&gt;</description><enclosure url="http://blogs.msdn.com/rimuri/attachment/913459.ashx" length="5218" type="application/octet-stream" /><category domain="http://blogs.msdn.com/rimuri/archive/tags/Team+Foundation+Server/default.aspx">Team Foundation Server</category></item><item><title>Reusable MSBuild Sandcastle Targets File</title><link>http://blogs.msdn.com/rimuri/archive/2006/10/30/reusable-msbuild-sandcastle-targets-file.aspx</link><pubDate>Tue, 31 Oct 2006 03:24:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:905088</guid><dc:creator>Richard Murillo</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/rimuri/comments/905088.aspx</comments><wfw:commentRss>http://blogs.msdn.com/rimuri/commentrss.aspx?PostID=905088</wfw:commentRss><wfw:comment>http://blogs.msdn.com/rimuri/rsscomments.aspx?PostID=905088</wfw:comment><description>&lt;P&gt;&lt;SPAN style="FONT-SIZE: 11pt; COLOR: #1f497d; FONT-FAMILY: 'Calibri','sans-serif'; mso-fareast-font-family: Calibri; mso-ansi-language: EN-US; mso-fareast-language: EN-US; mso-bidi-language: AR-SA; mso-fareast-theme-font: minor-latin; mso-bidi-font-family: 'Times New Roman'"&gt;Based on a past post, I have an external targets file you can place in your $(MSBuildExtensionsPath) folder (attached in zip).&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;SPAN style="COLOR: #1f497d"&gt;&lt;FONT size=3&gt;&lt;FONT face=Calibri&gt;You can call it like this:&lt;?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: Consolas"&gt;&amp;nbsp; &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: maroon; FONT-FAMILY: Consolas"&gt;Import&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: Consolas"&gt; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: red; FONT-FAMILY: Consolas"&gt;Project&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: Consolas"&gt;=&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Consolas"&gt;"&lt;SPAN style="COLOR: blue"&gt;$(MSBuildExtensionsPath)\Sandcastle.targets&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt;/&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #1f497d"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: Consolas"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: maroon; FONT-FAMILY: Consolas"&gt;Target&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: Consolas"&gt; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: red; FONT-FAMILY: Consolas"&gt;Name&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: Consolas"&gt;=&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Consolas"&gt;"&lt;SPAN style="COLOR: blue"&gt;AfterCompile&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt;&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: Consolas"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: maroon; FONT-FAMILY: Consolas"&gt;CallTarget&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: Consolas"&gt; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: red; FONT-FAMILY: Consolas"&gt;RunEachTargetSeparately&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: Consolas"&gt;=&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Consolas"&gt;"&lt;SPAN style="COLOR: blue"&gt;true&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Targets&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;=&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt;DocumentCLR&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;ContinueOnError&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;=&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt;false&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt;/&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: Consolas"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: maroon; FONT-FAMILY: Consolas"&gt;OnError&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: Consolas"&gt; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: red; FONT-FAMILY: Consolas"&gt;ExecuteTargets&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: Consolas"&gt;=&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Consolas"&gt;"&lt;SPAN style="COLOR: blue"&gt;OnBuildBreak;&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt;/&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: Consolas"&gt;&amp;nbsp; &amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: maroon; FONT-FAMILY: Consolas"&gt;Target&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: Consolas"&gt;&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: Consolas"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: maroon; FONT-FAMILY: Consolas"&gt;Target&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: Consolas"&gt; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: red; FONT-FAMILY: Consolas"&gt;Name&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: Consolas"&gt;=&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Consolas"&gt;"&lt;SPAN style="COLOR: blue"&gt;DocumentCLR&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt;&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: Consolas"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: maroon; FONT-FAMILY: Consolas"&gt;CallTarget&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: Consolas"&gt; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: red; FONT-FAMILY: Consolas"&gt;Targets&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: Consolas"&gt;=&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Consolas"&gt;"&lt;SPAN style="COLOR: blue"&gt;SandcastleDocument&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;ContinueOnError&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;=&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt;false&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt; /&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: Consolas"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: maroon; FONT-FAMILY: Consolas"&gt;MakeDir&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: Consolas"&gt; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: red; FONT-FAMILY: Consolas"&gt;Condition&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: Consolas"&gt;=&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Consolas"&gt;"&lt;SPAN style="COLOR: blue"&gt;!Exists('$(BinariesRoot)\Documentation')&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Directories&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;=&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt;$(BinariesRoot)\Documentation&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;ContinueOnError&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;=&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt;false&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt; /&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: Consolas"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: maroon; FONT-FAMILY: Consolas"&gt;Copy&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: Consolas"&gt; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: red; FONT-FAMILY: Consolas"&gt;SourceFiles&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: Consolas"&gt;=&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Consolas"&gt;"&lt;SPAN style="COLOR: blue"&gt;$(SandcastleWorkingDirectory)\Output\$(SandcastleDocumentationName).chm&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;DestinationFiles&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;=&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt;$(BinariesRoot)\Documentation\$(SandcastleDocumentationName).chm&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;ContinueOnError&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;=&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt;false&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt;/&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: Consolas"&gt;&amp;nbsp; &amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: maroon; FONT-FAMILY: Consolas"&gt;Target&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: Consolas"&gt;&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #1f497d"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="COLOR: #1f497d"&gt;&lt;o:p&gt;&lt;FONT face=Calibri size=3&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="COLOR: #1f497d"&gt;&lt;FONT size=3&gt;&lt;FONT face=Calibri&gt;The following is configuration from my msbuild response file:&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Consolas"&gt;/p:SandcastleDocumentationName=MyProjectDocumentation&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Consolas"&gt;/p:SandcastleConfiguration=C:\YOUR\CONFIG\sandcastle.config&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Consolas"&gt;/p:SandcastleDocumentationOutput=$(BinariesRoot)\Documentation&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Consolas"&gt;/p:SandcastleDependencies="%windir%\Microsoft.NET\Framework\v2.0.50727\*.dll,C:\YOUR\Dependencies\*.dll,%windir%\assembly\GAC_MSIL\Microsoft.VisualStudio.QualityTools.UnitTestFramework\8.0.0.0__b03f5f7f11d50a3a\Microsoft.VisualStudio.QualityTools.UnitTestFramework.dll"&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Consolas"&gt;/p:SandcastleHelpGeneration=CHM&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Consolas"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 11pt; COLOR: #1f497d; FONT-FAMILY: 'Calibri','sans-serif'; mso-fareast-font-family: Calibri; mso-ansi-language: EN-US; mso-fareast-language: EN-US; mso-bidi-language: AR-SA; mso-fareast-theme-font: minor-latin; mso-bidi-font-family: 'Times New Roman'"&gt;Note: tested with build 2.0.2426.28539&lt;/SPAN&gt;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=905088" width="1" height="1"&gt;</description><enclosure url="http://blogs.msdn.com/rimuri/attachment/905088.ashx" length="1269" type="application/x-zip-compressed" /><category domain="http://blogs.msdn.com/rimuri/archive/tags/Team+Foundation+Server/default.aspx">Team Foundation Server</category><category domain="http://blogs.msdn.com/rimuri/archive/tags/Visual+Studio/default.aspx">Visual Studio</category></item><item><title>VSTF Feature Request</title><link>http://blogs.msdn.com/rimuri/archive/2006/10/25/vstf-feature-request.aspx</link><pubDate>Wed, 25 Oct 2006 19:43:14 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:873220</guid><dc:creator>Richard Murillo</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/rimuri/comments/873220.aspx</comments><wfw:commentRss>http://blogs.msdn.com/rimuri/commentrss.aspx?PostID=873220</wfw:commentRss><wfw:comment>http://blogs.msdn.com/rimuri/rsscomments.aspx?PostID=873220</wfw:comment><description>&lt;p&gt;There have been several instances when working with multiple teams that they need to build different build configurations on the same build machine. For example, we have a central build type that encapsulates the compilation of the bits, database installation and unit testing, and packaging of the compiled bits into an MSI. We also have build configurations that separate each. With OOB functionality you get an error message with the details of a soap exception explaining that only one build can be run at a time, which is understandable, but what about queuing?
&lt;/p&gt;&lt;p&gt;To get around this issue, I built a queuing web site that can be used to invoke builds instead of through the team explorer. The code uses the thread pool to wait for the active build to complete then starts its build task&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=873220" width="1" height="1"&gt;</description></item></channel></rss>