<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://programminglinq.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>Marco Russo : Join, LINQ</title><link>http://programminglinq.com/blogs/marcorusso/archive/tags/Join/LINQ/default.aspx</link><description>Tags: Join, LINQ</description><dc:language>en</dc:language><generator>CommunityServer 2.1 SP2 (Build: 61129.2)</generator><item><title>To join or not to join: that is the question (in LINQ)</title><link>http://programminglinq.com/blogs/marcorusso/archive/2008/06/18/to-join-or-not-to-join-that-is-the-question-in-linq.aspx</link><pubDate>Tue, 17 Jun 2008 21:22:00 GMT</pubDate><guid isPermaLink="false">6f1fdd61-9c0b-497f-974b-3001d899dae0:132</guid><dc:creator>Marco.Russo</dc:creator><slash:comments>0</slash:comments><comments>http://programminglinq.com/blogs/marcorusso/comments/132.aspx</comments><wfw:commentRss>http://programminglinq.com/blogs/marcorusso/commentrss.aspx?PostID=132</wfw:commentRss><description>&lt;P&gt;A comment received by one reader of &lt;A class="" href="http://www.amazon.com/gp/product/0735624003/?tag=se04-20"&gt;Programming LINQ&lt;/A&gt; suggested me to underline a concept that is not so intuitive using LINQ, especially if you come from years of SQL coding.&lt;/P&gt;
&lt;P&gt;The idea is very simple. Two entities in LINQ might be related in the model. Whenever this happen, usually it is better to leverage on this existing relationship and not to write the join syntax in an explicit way.&amp;nbsp;If you are using&amp;nbsp;LINQ to SQL, the&amp;nbsp;generated SQL code might be&amp;nbsp;more performant or at least&amp;nbsp;correspondant to the one generated by writing an explicit join in your LINQ query. The less constraints in your query, the better.&lt;/P&gt;
&lt;P&gt;Let's look at an example on the Northwind database. Imagine you want to see&amp;nbsp;a list of all categories with a flag set for the one which a particular product belongs to. This is a SQL query we could write:&lt;FONT size=2&gt;&lt;/P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;SELECT&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; c&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;CategoryID&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; c&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;CategoryName&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;,&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;CASE&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;WHEN&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; p&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;ProductID &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;IS&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;NULL&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&amp;nbsp;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; THEN&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; 0&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ELSE&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; 1&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;END&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;AS&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; Selected&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;FROM&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; Categories c&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;LEFT&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;JOIN&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; Products p&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ON&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; p&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;CategoryID &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;=&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; c&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;CategoryID&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; AND&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; p&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;ProductID &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;=&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; 10&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;ORDER&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;BY&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; CategoryName&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;Ok, we can write the same query in many other ways, but there are several more complex situations where a LEFT JOIN is used to test the presence of an element in a related table. A correspondant LINQ query might be the following one:&lt;/P&gt;&lt;FONT color=#0000ff&gt;
&lt;P&gt;from&lt;/FONT&gt; c &lt;FONT color=#0000ff&gt;in&lt;/FONT&gt; dc.Categories&lt;BR&gt;&lt;FONT color=#0000ff&gt;orderby&lt;/FONT&gt; c.CategoryName&lt;BR&gt;&lt;FONT color=#0000ff&gt;join&lt;/FONT&gt; p &lt;FONT color=#0000ff&gt;in&lt;/FONT&gt; dc.Products.Where(p =&amp;gt; p.ProductID == 10)&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; on&lt;/FONT&gt; c.CategoryID &lt;FONT color=#0000ff&gt;equals&lt;/FONT&gt; p.CategoryID&amp;nbsp;&lt;BR&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; into&lt;/FONT&gt; pj&lt;BR&gt;&lt;FONT color=#0000ff&gt;from&lt;/FONT&gt; x &lt;FONT color=#0000ff&gt;in&lt;/FONT&gt; pj.DefaultIfEmpty()&lt;BR&gt;&lt;FONT color=#0000ff&gt;select&lt;/FONT&gt; &lt;FONT color=#0000ff&gt;new&lt;/FONT&gt; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; c.CategoryID,&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; c.CategoryName,&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Selected = x != &lt;FONT color=#0000ff&gt;null&lt;BR&gt;&lt;/FONT&gt;};&lt;/P&gt;
&lt;P&gt;The LINQ query above will generate a SQL query containing a LEFT JOIN statement. However, a relationship exists between Categories and Customer, and you can leverage on this relationship in the point where you really need to traverse the relationship (in the projection statement). The following one is a better way to get the same result:&lt;/P&gt;&lt;FONT color=#0000ff&gt;
&lt;P&gt;from&lt;/FONT&gt; c &lt;FONT color=#0000ff&gt;in&lt;/FONT&gt; dc.Categories&lt;BR&gt;&lt;FONT color=#0000ff&gt;orderby&lt;/FONT&gt; c.CategoryName&lt;BR&gt;&lt;FONT color=#0000ff&gt;select&lt;/FONT&gt; &lt;FONT color=#0000ff&gt;new&lt;/FONT&gt; { &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; c.CategoryID,&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; c.CategoryName,&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Selected = c.Products.Any( p =&amp;gt; p.ProductID == 10 ) ? &lt;FONT color=#0000ff&gt;true&lt;/FONT&gt; : &lt;FONT color=#0000ff&gt;false&lt;/FONT&gt; &lt;BR&gt;};&lt;/P&gt;
&lt;P&gt;This new version has two advantages. First, it&amp;nbsp;is shorter and&amp;nbsp;express its intent more explicitly. &amp;nbsp;Second, it generates a SQL query with an EXISTS statement, similar to the following one.&lt;/P&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;SELECT&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; CategoryID&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;,&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; CategoryName&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;,&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; (&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;CASE&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#808080&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/FONT&gt;WHEN&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT color=#808080 size=2&gt;EXISTS(&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#808080&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/FONT&gt;SELECT&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;NULL&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;AS&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; [EMPTY]&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#808080&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/FONT&gt;FROM&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; Products &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;AS&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; p&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#808080&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/FONT&gt;WHERE&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;(&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;p&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;ProductID &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;=&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; 10&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;)&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;AND&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;(&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;p&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;CategoryID &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;=&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; c&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;CategoryID&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;)&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; )&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;THEN&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; 1&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#808080&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/FONT&gt;ELSE&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; 0&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#808080&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/FONT&gt;END&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;&lt;FONT color=#808080 size=2&gt;)&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;AS&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; Selected&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;FROM&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; Categories &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;AS&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; c&lt;BR&gt;&lt;FONT color=#0000ff&gt;ORDER&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;BY&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt; CategoryName&lt;/FONT&gt;&lt;/P&gt;&lt;/FONT&gt;
&lt;P&gt;The execution plan used by SQL Server might be similar if not equal. However, using the implicit relationship between Categories and Products in the LINQ query is usually better, because it gives more freedom to the LINQ provider to generate a more efficient SQL code.&lt;/P&gt;&lt;img src="http://programminglinq.com/aggbug.aspx?PostID=132" width="1" height="1"&gt;</description><category domain="http://programminglinq.com/blogs/marcorusso/archive/tags/LINQ/default.aspx">LINQ</category><category domain="http://programminglinq.com/blogs/marcorusso/archive/tags/Join/default.aspx">Join</category></item></channel></rss>