<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Chad Scharf&#039;s Weblog &#187; LINQ</title>
	<atom:link href="http://www.chadscharf.com/index.php/categories/linq/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.chadscharf.com</link>
	<description>It&#039;s always time to upgrade!</description>
	<lastBuildDate>Fri, 28 Oct 2011 22:14:08 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>Readability, Sub-Queries in LINQ</title>
		<link>http://www.chadscharf.com/index.php/2008/03/readability-sub-queries-in-linq/</link>
		<comments>http://www.chadscharf.com/index.php/2008/03/readability-sub-queries-in-linq/#comments</comments>
		<pubDate>Sun, 30 Mar 2008 18:39:00 +0000</pubDate>
		<dc:creator>Chad</dc:creator>
				<category><![CDATA[LINQ]]></category>
		<category><![CDATA[c#]]></category>
		<category><![CDATA[linq to sql]]></category>

		<guid isPermaLink="false">http://chadscharf.com/post.aspx?id=142938bb-425a-4c87-996e-eff575e58117</guid>
		<description><![CDATA[I&#8217;ve been working with LINQ and LINQ to SQL for a while now and I have to say, it definitely makes object enumeration, data access and binding extremely easy and efficient. Even the dynamic SQL it generates using LINQ to SQL is acceptable in efficiency and performance. One thing I noticed however is when you [...]<p><a href="http://www.chadscharf.com/index.php/2008/03/readability-sub-queries-in-linq/">Readability, Sub-Queries in LINQ</a> is a post from: <a href="http://www.chadscharf.com">Chad Scharf&#039;s Weblog</a>. For software consulting services please visit <a href="http://www.scharfholdings.com">Scharf Holdings, LLC</a></p>
]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been working with LINQ and LINQ to SQL for a while now and I have to say, it definitely makes object enumeration, data access and binding extremely easy and efficient. Even the dynamic SQL it generates using LINQ to SQL is acceptable in efficiency and performance. One thing I noticed however is when you need to do complex sub queries or provide summary information within nested levels of relationships, the code can become pretty messy, until I discovered you can write LINQ statements within a generic type from inside an existing LINQ statement.</p>
<p>I&#8217;m sure somewhere in the documentation it says you can do this, but I just discovered it for myself, so no laughing if you&#8217;re thinking to yourself, &#8220;DUH; what a moron!&#8221; <span id="more-10"></span></p>
<h2>Setting up the LINQ to SQL DBML</h2>
<p>Below is an example that I set up using everyone&#8217;s favorite Northwind database (which had to be installed separately on SQL 2005 for good reason). First I created a simple console application targeted for the .NET 3.5 Framework and added a LINQ to SQL class (dbml) called &#8220;Northwind&#8221; which created my NorthwindDataContext class.</p>
<p><img src="/files/033008_2032_Readability1.jpg" alt="" width="504" height="311" /></p>
<p>For this example I&#8217;m using the Employee, Order, and Order_Detail table in order to calculate employee commission at 10%. You could also use LINQ to Objects or LINQ to XML in this same fashion as I&#8217;m about to show below.</p>
<p>In the code, my first attempt at doing this calculation was pretty hard to read and involved nested Lambda expressions, which of and in themselves can be difficult to read.</p>
<p><span style="font-size: 10pt; font-family: Courier New"><span style="color: blue">using</span> (<span style="color: #2b91af">NorthwindDataContext</span> northwind = <span style="color: blue">new</span> <span style="color: #2b91af">NorthwindDataContext</span>()) </span><br />
<span style="font-size: 10pt; font-family: Courier New">{ </span><br />
<span style="font-size: 10pt; font-family: Courier New">Â Â Â Â <span style="color: blue">var</span> employees = <span style="color: blue">from</span> e <span style="color: blue">in</span> northwind.Employees </span><br />
<span style="font-size: 10pt; font-family: Courier New">Â Â Â Â  <span style="color: blue">select</span> <span style="color: blue">new </span></span><br />
<span style="font-size: 10pt; font-family: Courier New">Â Â Â Â  { </span><br />
<span style="font-size: 10pt; font-family: Courier New">Â Â Â Â  FirstName = e.FirstName, </span><br />
<span style="font-size: 10pt; font-family: Courier New">Â Â Â Â  LastName = e.LastName, </span><br />
<span style="font-size: 10pt; font-family: Courier New">Â Â Â Â  Title = e.Title, </span><br />
<span style="font-size: 10pt; font-family: Courier New">Â Â Â Â  Commission = e.Orders </span><br />
<span style="font-size: 10pt; font-family: Courier New">Â Â Â Â  .Sum(r =&gt; r.Order_Details </span><br />
<span style="font-size: 10pt; font-family: Courier New">Â Â Â Â  .Where(r1 =&gt; r1.Order.ShippedDate.HasValue &amp;&amp; r1.Order.ShippedDate &lt; <span style="color: #2b91af">DateTime</span>.Today.AddDays(-1)) </span><br />
<span style="font-size: 10pt; font-family: Courier New">Â Â Â Â  .Sum(r2 =&gt; (r2.Quantity * r2.UnitPrice) &#8211; <span style="color: #2b91af">Convert</span>.ToDecimal(r2.Discount)) * .1M) </span><br />
<span style="font-size: 10pt; font-family: Courier New">Â Â Â Â  }; </span><br />
<span style="font-size: 10pt; font-family: Courier New">Â Â Â Â <span style="color: blue">foreach</span> (<span style="color: blue">var</span> emp <span style="color: blue">in</span> employees) </span><br />
<span style="font-size: 10pt; font-family: Courier New">Â Â Â Â { </span><br />
<span style="font-size: 10pt; font-family: Courier New">Â Â Â Â Â Â Â Â <span style="color: #2b91af">Console</span>.WriteLine(<span style="color: #a31515">&#8220;First Name\tLast Name\tTitle\tCommission&#8221;</span>); </span><br />
<span style="font-size: 10pt; font-family: Courier New">Â Â Â Â Â Â Â Â <span style="color: #2b91af">Console</span>.WriteLine(<span style="color: #a31515">&#8220;{0}\t{1}\t{2}\t{3:C}&#8221;</span>, </span><br />
<span style="font-size: 10pt; font-family: Courier New">Â Â Â Â Â Â Â Â Â Â Â Â emp.FirstName, </span><br />
<span style="font-size: 10pt; font-family: Courier New">Â Â Â Â Â Â Â Â Â Â Â Â emp.LastName, </span><br />
<span style="font-size: 10pt; font-family: Courier New">Â Â Â Â Â Â Â Â Â Â Â Â emp.Title, </span><br />
<span style="font-size: 10pt; font-family: Courier New">Â Â Â Â Â Â Â Â Â Â Â Â emp.Commission); </span><br />
<span style="font-size: 10pt; font-family: Courier New">Â Â Â Â } </span><br />
<span style="font-size: 10pt; font-family: Courier New">} </span></p>
<p>Then, after looking at this code, I figured I would give a shot at selecting commission using another LINQ statement within the new generic class I was creating. The result looked like this:</p>
<p><span style="font-size: 10pt; font-family: Courier New"><span style="color: blue">using</span> (<span style="color: #2b91af">NorthwindDataContext</span> northwind = <span style="color: blue">new</span> <span style="color: #2b91af">NorthwindDataContext</span>()) </span><br />
<span style="font-size: 10pt; font-family: Courier New">{ </span><br />
<span style="font-size: 10pt; font-family: Courier New">Â Â Â Â <span style="color: blue">var</span> employees = <span style="color: blue">from</span> e <span style="color: blue">in</span> northwind.Employees </span><br />
<span style="font-size: 10pt; font-family: Courier New">Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â <span style="color: blue">select</span> <span style="color: blue">new </span></span><br />
<span style="font-size: 10pt; font-family: Courier New">Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â { </span><br />
<span style="font-size: 10pt; font-family: Courier New">Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â FirstName = e.FirstName, </span><br />
<span style="font-size: 10pt; font-family: Courier New">Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â LastName = e.LastName, </span><br />
<span style="font-size: 10pt; font-family: Courier New">Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Title = e.Title, </span><br />
<span style="font-size: 10pt; font-family: Courier New">Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Commission = (<span style="color: blue">from</span> t <span style="color: blue">in</span> e.Orders </span><br />
<span style="font-size: 10pt; font-family: Courier New">Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â  <span style="color: blue">where</span> t.ShippedDate.HasValue &amp;&amp; t.ShippedDate &lt; <span style="color: #2b91af">DateTime</span>.Today.AddDays(-1) </span><br />
<span style="font-size: 10pt; font-family: Courier New">Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â  <span style="color: blue">select</span> t.Order_Details.Sum(r =&gt; (r.Quantity * r.UnitPrice) &#8211; <span style="color: #2b91af">Convert</span>.ToDecimal(r.Discount)) * .1M).Sum(r =&gt; r) </span><br />
<span style="font-size: 10pt; font-family: Courier New">Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â }; </span><br />
<span style="font-size: 10pt; font-family: Courier New">Â Â Â Â <span style="color: blue">foreach</span> (<span style="color: blue">var</span> emp <span style="color: blue">in</span> employees) </span><br />
<span style="font-size: 10pt; font-family: Courier New">Â Â Â Â { </span><br />
<span style="font-size: 10pt; font-family: Courier New">Â Â Â Â Â Â Â Â <span style="color: #2b91af">Console</span>.WriteLine(<span style="color: #a31515">&#8220;First Name\tLast Name\tTitle\tCommission&#8221;</span>); </span><br />
<span style="font-size: 10pt; font-family: Courier New">Â Â Â Â Â Â Â Â <span style="color: #2b91af">Console</span>.WriteLine(<span style="color: #a31515">&#8220;{0}\t{1}\t{2}\t{3:C}&#8221;</span>, </span><br />
<span style="font-size: 10pt; font-family: Courier New">Â Â Â Â Â Â Â Â Â Â Â Â emp.FirstName, </span><br />
<span style="font-size: 10pt; font-family: Courier New">Â Â Â Â Â Â Â Â Â Â Â Â emp.LastName, </span><br />
<span style="font-size: 10pt; font-family: Courier New">Â Â Â Â Â Â Â Â Â Â Â Â emp.Title, </span><br />
<span style="font-size: 10pt; font-family: Courier New">Â Â Â Â Â Â Â Â Â Â Â Â emp.Commission); </span><br />
<span style="font-size: 10pt; font-family: Courier New">Â Â Â Â } </span><br />
<span style="font-size: 10pt; font-family: Courier New">} </span></p>
<h2>SQL Output</h2>
<p>The output from the 2 above LINQ statements was as follows:</p>
<p><span style="font-size: 10pt; font-family: Courier New"><span style="color: blue">SELECT</span> [t0]<span style="color: gray">.</span>[FirstName]<span style="color: gray">,</span> [t0]<span style="color: gray">.</span>[LastName]<span style="color: gray">,</span> [t0]<span style="color: gray">.</span>[Title]<span style="color: gray">,</span> <span style="color: gray">( </span></span><br />
<span style="font-size: 10pt; font-family: Courier New"><span style="color: blue">SELECT</span> <span style="color: fuchsia">SUM</span><span style="color: gray">(</span>[t4]<span style="color: gray">.</span>[value]<span style="color: gray">) </span></span><br />
<span style="font-size: 10pt; font-family: Courier New"><span style="color: blue">FROM</span> <span style="color: gray">( </span></span><br />
<span style="font-size: 10pt; font-family: Courier New"><span style="color: blue">SELECT</span> <span style="color: gray">(( </span></span><br />
<span style="font-size: 10pt; font-family: Courier New"><span style="color: blue">SELECT</span> <span style="color: fuchsia">SUM</span><span style="color: gray">(</span>[t3]<span style="color: gray">.</span>[value]<span style="color: gray">) </span></span><br />
<span style="font-size: 10pt; font-family: Courier New"><span style="color: blue">FROM</span> <span style="color: gray">( </span></span><br />
<span style="font-size: 10pt; font-family: Courier New"><span style="color: blue">SELECT</span> <span style="color: gray">((</span><span style="color: fuchsia">CONVERT</span><span style="color: gray">(</span><span style="color: blue">Decimal</span><span style="color: gray">(</span>29<span style="color: gray">,</span>4<span style="color: gray">),</span>[t2]<span style="color: gray">.</span>[Quantity]<span style="color: gray">))</span> <span style="color: gray">*</span> [t2]<span style="color: gray">.</span>[UnitPrice]<span style="color: gray">)</span> <span style="color: gray">-</span> <span style="color: gray">(</span><span style="color: fuchsia">CONVERT</span><span style="color: gray">(</span><span style="color: blue">Decimal</span><span style="color: gray">(</span>29<span style="color: gray">,</span>4<span style="color: gray">),</span>[t2]<span style="color: gray">.</span>[Discount]<span style="color: gray">))</span> <span style="color: blue">AS</span> [value]<span style="color: gray">,</span> [t2]<span style="color: gray">.</span>[OrderID] </span><br />
<span style="font-size: 10pt; font-family: Courier New"><span style="color: blue">FROM</span> [dbo]<span style="color: gray">.</span>[Order Details] <span style="color: blue">AS</span> [t2] </span><br />
<span style="font-size: 10pt; font-family: Courier New"><span style="color: gray">)</span> <span style="color: blue">AS</span> [t3] </span><br />
<span style="font-size: 10pt; font-family: Courier New"><span style="color: blue">WHERE</span> <span style="color: gray">(</span>[t1]<span style="color: gray">.</span>[ShippedDate] <span style="color: gray">IS</span> <span style="color: gray">NOT</span> <span style="color: gray">NULL)</span> <span style="color: gray">AND</span> <span style="color: gray">(</span>[t1]<span style="color: gray">.</span>[ShippedDate] <span style="color: gray">&lt;</span> <span style="color: red">&#8217;2008-03-27 00:00:00.000&#8242;</span><span style="color: gray">)</span> <span style="color: gray">AND</span> <span style="color: gray">(</span>[t3]<span style="color: gray">.</span>[OrderID] <span style="color: gray">=</span> [t1]<span style="color: gray">.</span>[OrderID]<span style="color: gray">) </span></span><br />
<span style="font-size: 10pt; font-family: Courier New"><span style="color: gray">))</span> <span style="color: gray">*</span> 0.1 <span style="color: blue">AS</span> [value]<span style="color: gray">,</span> [t1]<span style="color: gray">.</span>[EmployeeID] </span><br />
<span style="font-size: 10pt; font-family: Courier New"><span style="color: blue">FROM</span> [dbo]<span style="color: gray">.</span>[Orders] <span style="color: blue">AS</span> [t1] </span><br />
<span style="font-size: 10pt; font-family: Courier New"><span style="color: gray">)</span> <span style="color: blue">AS</span> [t4] </span><br />
<span style="font-size: 10pt; font-family: Courier New"><span style="color: blue">WHERE</span> [t4]<span style="color: gray">.</span>[EmployeeID] <span style="color: gray">=</span> [t0]<span style="color: gray">.</span>[EmployeeID] </span><br />
<span style="font-size: 10pt; font-family: Courier New"><span style="color: gray">)</span> <span style="color: blue">AS</span> [Commission] </span><br />
<span style="font-size: 10pt; font-family: Courier New"><span style="color: blue">FROM</span> [dbo]<span style="color: gray">.</span>[Employees] <span style="color: blue">AS</span> [t0] </span></p>
<p>Compared with the revised code:</p>
<p><span style="font-size: 10pt; font-family: Courier New"><span style="color: blue">SELECT</span> [t0]<span style="color: gray">.</span>[FirstName]<span style="color: gray">,</span> [t0]<span style="color: gray">.</span>[LastName]<span style="color: gray">,</span> [t0]<span style="color: gray">.</span>[Title]<span style="color: gray">,</span> <span style="color: gray">( </span></span><br />
<span style="font-size: 10pt; font-family: Courier New"><span style="color: blue">SELECT</span> <span style="color: fuchsia">SUM</span><span style="color: gray">(</span>[t4]<span style="color: gray">.</span>[value]<span style="color: gray">) </span></span><br />
<span style="font-size: 10pt; font-family: Courier New"><span style="color: blue">FROM</span> <span style="color: gray">( </span></span><br />
<span style="font-size: 10pt; font-family: Courier New"><span style="color: blue">SELECT</span> <span style="color: gray">(( </span></span><br />
<span style="font-size: 10pt; font-family: Courier New"><span style="color: blue">SELECT</span> <span style="color: fuchsia">SUM</span><span style="color: gray">(</span>[t3]<span style="color: gray">.</span>[value]<span style="color: gray">) </span></span><br />
<span style="font-size: 10pt; font-family: Courier New"><span style="color: blue">FROM</span> <span style="color: gray">( </span></span><br />
<span style="font-size: 10pt; font-family: Courier New"><span style="color: blue">SELECT</span> <span style="color: gray">((</span><span style="color: fuchsia">CONVERT</span><span style="color: gray">(</span><span style="color: blue">Decimal</span><span style="color: gray">(</span>29<span style="color: gray">,</span>4<span style="color: gray">),</span>[t2]<span style="color: gray">.</span>[Quantity]<span style="color: gray">))</span> <span style="color: gray">*</span> [t2]<span style="color: gray">.</span>[UnitPrice]<span style="color: gray">)</span> <span style="color: gray">-</span> <span style="color: gray">(</span><span style="color: fuchsia">CONVERT</span><span style="color: gray">(</span><span style="color: blue">Decimal</span><span style="color: gray">(</span>29<span style="color: gray">,</span>4<span style="color: gray">),</span>[t2]<span style="color: gray">.</span>[Discount]<span style="color: gray">))</span> <span style="color: blue">AS</span> [value]<span style="color: gray">,</span> [t2]<span style="color: gray">.</span>[OrderID] </span><br />
<span style="font-size: 10pt; font-family: Courier New"><span style="color: blue">FROM</span> [dbo]<span style="color: gray">.</span>[Order Details] <span style="color: blue">AS</span> [t2] </span><br />
<span style="font-size: 10pt; font-family: Courier New"><span style="color: gray">)</span> <span style="color: blue">AS</span> [t3] </span><br />
<span style="font-size: 10pt; font-family: Courier New"><span style="color: blue">WHERE</span> [t3]<span style="color: gray">.</span>[OrderID] <span style="color: gray">=</span> [t1]<span style="color: gray">.</span>[OrderID] </span><br />
<span style="font-size: 10pt; font-family: Courier New"><span style="color: gray">))</span> <span style="color: gray">*</span> 0.1 <span style="color: blue">AS</span> [value]<span style="color: gray">,</span> [t1]<span style="color: gray">.</span>[ShippedDate]<span style="color: gray">,</span> [t1]<span style="color: gray">.</span>[EmployeeID] </span><br />
<span style="font-size: 10pt; font-family: Courier New"><span style="color: blue">FROM</span> [dbo]<span style="color: gray">.</span>[Orders] <span style="color: blue">AS</span> [t1] </span><br />
<span style="font-size: 10pt; font-family: Courier New"><span style="color: gray">)</span> <span style="color: blue">AS</span> [t4] </span><br />
<span style="font-size: 10pt; font-family: Courier New"><span style="color: blue">WHERE</span> <span style="color: gray">(</span>[t4]<span style="color: gray">.</span>[ShippedDate] <span style="color: gray">IS</span> <span style="color: gray">NOT</span> <span style="color: gray">NULL)</span> <span style="color: gray">AND</span> <span style="color: gray">(</span>[t4]<span style="color: gray">.</span>[ShippedDate] <span style="color: gray">&lt;</span> <span style="color: red">&#8217;2008-03-27 00:00:00.000&#8242;</span><span style="color: gray">)</span> <span style="color: gray">AND</span> <span style="color: gray">(</span>[t4]<span style="color: gray">.</span>[EmployeeID] <span style="color: gray">=</span> [t0]<span style="color: gray">.</span>[EmployeeID]<span style="color: gray">) </span></span><br />
<span style="font-size: 10pt; font-family: Courier New"><span style="color: gray">)</span> <span style="color: blue">AS</span> [Commission] </span><br />
<span style="font-size: 10pt; font-family: Courier New"><span style="color: blue">FROM</span> [dbo]<span style="color: gray">.</span>[Employees] <span style="color: blue">AS</span> [t0] </span></p>
<h2>Conclusion</h2>
<p>Both of these sets of code produce SQL that returns the exact same results from the database, however the joins that they use and indexes are very different, and the second one that is not only easier to read also shows lower consumption and more efficiency in the execution plan than the first. The first query took consistently between 334 and 386 miliseconds longer than the second, although both executed under one second after the queries were cached by SQL Server.</p>
<p><a href="http://www.chadscharf.com/index.php/2008/03/readability-sub-queries-in-linq/">Readability, Sub-Queries in LINQ</a> is a post from: <a href="http://www.chadscharf.com">Chad Scharf&#039;s Weblog</a>. For software consulting services please visit <a href="http://www.scharfholdings.com">Scharf Holdings, LLC</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.chadscharf.com/index.php/2008/03/readability-sub-queries-in-linq/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>

