<?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 : C#</title><link>http://blogs.msdn.com/rimuri/archive/tags/C_2300_/default.aspx</link><description>Tags: C#</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>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>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></channel></rss>