<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-8924020273529189874</id><updated>2011-11-27T16:08:31.628-08:00</updated><title type='text'>Adventures in .NET-dom</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://dotnetdom.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8924020273529189874/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://dotnetdom.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>J²</name><uri>http://www.blogger.com/profile/14478332251437579476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://photos1.blogger.com/img/268/3041/1024/IMGP17751.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>18</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-8924020273529189874.post-91754717050361732</id><published>2011-02-18T08:35:00.000-08:00</published><updated>2011-02-18T08:35:00.514-08:00</updated><title type='text'>Load Testing with Google's WebDriver</title><content type='html'>&lt;div&gt;I have been working with &lt;a href="http://code.google.com/p/selenium/"&gt;WebDriver/Selenium 2&lt;/a&gt; for some time now; I implemented it for my team at work and have since discovered ways to do load testing.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I code primarily in C#, but if this were to be done in Java you could take advantage of the headless browser driver (&lt;a href="http://code.google.com/p/selenium/wiki/HtmlUnitDriver"&gt;HtmlUnitDriver&lt;/a&gt;), which would allow you to potentially run 100s of tests at once. &lt;a href="http://www.ikvm.net/"&gt;IKVM&lt;/a&gt; allows you to convert this to C#, but when I did this I discovered that a 5 second test took 2 minutes or more to run, and I wasn't willing to deal with that.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;A viable option for a headless browser I found for C# is an open source project called &lt;a href="https://github.com/axefrog/SimpleBrowser"&gt;SimpleBrowser&lt;/a&gt;, it doesn't support JavaScript but it's the foundation for a bigger project called &lt;a href="https://github.com/axefrog/XBrowser"&gt;XBrowser&lt;/a&gt; that will support not only JavaScript but HTML5, SVG, and Canvas.&lt;/div&gt;&lt;div&gt;It's not implemented in WebDriver but I was easily able to run 100 concurrent instances of SimpleBrowser performing a simple test.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Anyway, on to the code: &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/-E8TXRZjP33A/TV1dQVTV9iI/AAAAAAAAAAU/KyKi2lkawpk/s1600/code.png"&gt;&lt;img style="cursor:pointer; cursor:hand; width:599; height:323;" src="http://2.bp.blogspot.com/-E8TXRZjP33A/TV1dQVTV9iI/AAAAAAAAAAU/KyKi2lkawpk/s1600/code.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5574714448932107810" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Some notes:&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;You will need to use a delegate to pass parameters to the test, in this case I've used a lambda expression.&lt;/li&gt;&lt;li&gt;I've run into problems trying to run this as a unit test:&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;For some reason, a unit test doesn't run the threads all at once, instead it will run them&lt;span class="Apple-style-span" style="white-space: pre;"&gt; &lt;/span&gt;one at a time.&lt;/li&gt;&lt;li&gt;You will have to spin the main thread while it waits for the other threads to finish.&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Recommended reading:&lt;/div&gt;&lt;div&gt;&lt;a href="http://www.albahari.com/threading/"&gt;http://www.albahari.com/threading/&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8924020273529189874-91754717050361732?l=dotnetdom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dotnetdom.blogspot.com/feeds/91754717050361732/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dotnetdom.blogspot.com/2011/02/load-testing-with-googles-webdriver.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8924020273529189874/posts/default/91754717050361732'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8924020273529189874/posts/default/91754717050361732'/><link rel='alternate' type='text/html' href='http://dotnetdom.blogspot.com/2011/02/load-testing-with-googles-webdriver.html' title='Load Testing with Google&apos;s WebDriver'/><author><name>Anders</name><uri>http://www.blogger.com/profile/06483623816130068969</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-E8TXRZjP33A/TV1dQVTV9iI/AAAAAAAAAAU/KyKi2lkawpk/s72-c/code.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8924020273529189874.post-9150226976303753051</id><published>2009-07-10T10:28:00.000-07:00</published><updated>2009-07-10T13:10:30.072-07:00</updated><title type='text'>Combining Lambda Expressions</title><content type='html'>I'm working on custom fields for a GridView which can include custom filters.  The idea is to persist these filters to the data layer, so that when a filter is applied, the query sent to the database includes all the appropriate "where" clauses.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I wanted to have an abstract parent class that deals with most of the tedium involved in extending the DataControlField class, and then only require the child classes to handle the cases specific to their custom filters.  The parent class would know how to create the lambda expression required to get a given property off of the object that is being represented in the GridView, while the child class would know how to filter by that property.  I was willing to make the parent class a little more messy, as long as it could easily be extended to make whatever kind of filterable columns we wanted.  For example, if the child class was filtering based on string data types, I wanted to make the following syntax possible:&lt;/div&gt;&lt;div&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;protected override IEnumerable&amp;lt;Expression&amp;lt;Func&amp;lt;string, bool&amp;gt;&amp;gt;&amp;gt; GetFilters()&lt;br /&gt;{&lt;br /&gt;   if (filterTextBox.Text != null &amp;amp;&amp;amp; filterTextBox.Text.Length &amp;gt; 0)&lt;br /&gt;   {&lt;br /&gt;       yield return s =&amp;gt; s.StartsWith(filterTextBox.Text);&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;But I ran into a wall trying to get the parent class to build the full filter expression based on this partial filter expression.  I needed a method that looked like this:&lt;/div&gt;&lt;div&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;public Expression&amp;lt;Func&amp;lt;TrackedTime, bool&amp;gt;&amp;gt; mergeFilterExpressions(&lt;br /&gt;   Expression&amp;lt;Func&amp;lt;TrackedTime, T&amp;gt;&amp;gt; propGetter,&lt;br /&gt;   Expression&amp;lt;Func&amp;lt;T, bool&amp;gt;&amp;gt; filter)&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;So given one expression that could get the property from the TrackedTime, and another expression that could get a boolean value from the property, I needed to be able to create an Expression that gets a boolean value from the TrackedTime.  In LINQ itself, there is of course the ability to Invoke the functions represented by my expressions, like this:&lt;div&gt;&lt;div&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;return tt =&amp;gt; filter.Invoke(propGetter.Invoke(tt));&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;However, LINQ to Entities &lt;i&gt;doesn't support the Invoke command&lt;/i&gt;.  So although this would compile just fine, it would throw a runtime exception when the time came to build the SQL query to send to the database.  It was driving me crazy.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;After much searching, it was Joe Albahari, creator of the amazing &lt;a href="http://www.linqpad.net/"&gt;LinqPad&lt;/a&gt; (which I use almost daily by the way), who had the solution.  On his &lt;a href="http://www.albahari.com/nutshell/linqkit.aspx"&gt;website&lt;/a&gt;, he provides a collection of extension methods called LinqKit, which allowed me to do the following:&lt;/div&gt;&lt;div&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;public Expression&amp;lt;Func&amp;lt;TrackedTime, bool&amp;gt;&amp;gt; mergeFilterExpressions(&lt;br /&gt;Expression&amp;lt;Func&amp;lt;TrackedTime, T&amp;gt;&amp;gt; propGetter,&lt;br /&gt;Expression&amp;lt;Func&amp;lt;T, bool&amp;gt;&amp;gt; filter)&lt;br /&gt;{&lt;br /&gt;   ParameterExpression param = propGetter.Parameters[0];&lt;br /&gt;   InvocationExpression getProp = Expression.Invoke(propGetter, param);&lt;br /&gt;   InvocationExpression invoke = Expression.Invoke(filter, getProp.Expand());&lt;br /&gt;   return Expression.Lambda&amp;lt;Func&amp;lt;TrackedTime, bool&amp;gt;&amp;gt;(invoke.Expand(), param);&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;How 'bout that!  By Invoking &lt;i&gt;and then Expanding&lt;/i&gt; the Expressions, I can now combine Lambda Expressions any way I want!&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8924020273529189874-9150226976303753051?l=dotnetdom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dotnetdom.blogspot.com/feeds/9150226976303753051/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dotnetdom.blogspot.com/2009/07/combining-lambda-expressions.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8924020273529189874/posts/default/9150226976303753051'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8924020273529189874/posts/default/9150226976303753051'/><link rel='alternate' type='text/html' href='http://dotnetdom.blogspot.com/2009/07/combining-lambda-expressions.html' title='Combining Lambda Expressions'/><author><name>J²</name><uri>http://www.blogger.com/profile/14478332251437579476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://photos1.blogger.com/img/268/3041/1024/IMGP17751.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8924020273529189874.post-4885552889705154836</id><published>2009-06-04T11:01:00.001-07:00</published><updated>2009-06-04T11:01:39.673-07:00</updated><title type='text'>Would a Wave-based IDE be feasible</title><content type='html'>&lt;span class="Apple-style-span" style="font-family: 'Times New Roman'; "&gt;&lt;div style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 3px; padding-right: 3px; padding-bottom: 3px; padding-left: 3px; width: auto; font: normal normal normal 100%/normal Georgia, serif; text-align: left; "&gt;Google recently announced "&lt;a href="http://wave.google.com/"&gt;Google Wave&lt;/a&gt;," a project that they've been working on for the past two years, and which is set to revolutionize online communication as we know it.  When it was announced, they mentioned that the whole thing was built using &lt;a href="http://code.google.com/webtoolkit/"&gt;Google's Web Toolkit&lt;/a&gt;.  I started looking into the toolkit and noticed that they also have something called the &lt;a href="http://code.google.com/appengine/"&gt;Google App Engine&lt;/a&gt;, which is a framework and service that lets you host your applications and data "in the cloud" on Google's servers.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Pondering on these various Internet technologies, I got to wondering:  Would it be possible to host the entire development process online?  If someone could create a Wave-based code infrastructure, we could have an online IDE:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;Each Java code file could be a Wave, which could be edited collaboratively--by multiple users at the same time, if necessary (hello &lt;a href="http://en.wikipedia.org/wiki/Extreme_Programming_Practices#Pair_programming"&gt;Extreme Programming&lt;/a&gt;!).  &lt;/li&gt;&lt;li&gt;A spell-check-like plugin could be created to provide real-time compiler feedback and intellisense.  &lt;/li&gt;&lt;li&gt;A bot could be granted access to the code tree in order to compile and deploy changes to a cloud-based service in real-time, provide debugging services, and even run unit tests.&lt;/li&gt;&lt;li&gt;Developers could "check out" the waves into their own framework instance, and once a set of changes is ready, they could be merged into the "stable" set of Waves.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Waves have a built-in, extremely powerful version control system built in already; you can visually and immediately step back to each point in a file's revision history to watch its evolution.&lt;/li&gt;&lt;li&gt;The Google folks already showed how useful Waves can be in bug management; bugs and tasks could be handled and passed around within the same Wave framework.  They could probably even be linked to the code changes that were made to fix them (and vice versa), for future reference.&lt;/li&gt;&lt;li&gt;A plugin similar to the bug management one could be used to tag a spot in code for colleague review.  A Wave thus tagged would appear in the colleague's inbox, where they could see the changes made in the context of the entire Java file.  They could start a thread inline in the code to ask questions and make suggestions, which would all be immediately visible to the original programmer.  They could even have an entire chat session right there, inline with the code!  Both the original programmer and the colleague could make and see the changes in real-time.  Once the colleague is satisfied, they could use the plugin to sign off on the changes.&lt;/li&gt;&lt;li&gt;Documentation (both internal and external) could also be managed by the same system. Code for a particular feature could be linked to that feature's documentation.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;And perhaps the best part about the whole thing is that developers don't even need to install anything on their computers.  They can log in from any web-enabled computer, anywhere, and all the same capabilities are at their fingertips.  With Wave, Google has laid the foundation for a new generation of Internet technologies.  I'm excited to see the many ways that this sort of technology will be leveraged in the years to come.&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8924020273529189874-4885552889705154836?l=dotnetdom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dotnetdom.blogspot.com/feeds/4885552889705154836/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dotnetdom.blogspot.com/2009/06/would-wave-based-ide-be-feasible.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8924020273529189874/posts/default/4885552889705154836'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8924020273529189874/posts/default/4885552889705154836'/><link rel='alternate' type='text/html' href='http://dotnetdom.blogspot.com/2009/06/would-wave-based-ide-be-feasible.html' title='Would a Wave-based IDE be feasible'/><author><name>J²</name><uri>http://www.blogger.com/profile/14478332251437579476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://photos1.blogger.com/img/268/3041/1024/IMGP17751.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8924020273529189874.post-461415429850165137</id><published>2009-05-04T13:00:00.000-07:00</published><updated>2009-05-04T13:54:40.025-07:00</updated><title type='text'>Fastest way to check for existence in a table</title><content type='html'>In order to improve performance on one of the pages in our Java code, I was making a SQL query which, along with the typical section grade information, also pulls in a field to tell whether that particular grade type is in use.  Between my own brains and some quick Google searching, this was the best query I could come up with:&lt;div&gt;&lt;div id="Panel1" class="OuterPanel"&gt;&lt;div id="OuterPanel" class="CodeViewPanel"&gt;&lt;table id="CodeTable" border="0"&gt;   &lt;tbody&gt;&lt;tr id="Row1"&gt;    &lt;td id="Lines" class="Lines"&gt;&lt;pre&gt;1&lt;br /&gt;2&lt;br /&gt;3&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td id="SourceCode" class="Code"&gt;&lt;span id="CodeText"&gt;&lt;pre&gt;&lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=select&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color:#0000FF"&gt;select&lt;/a&gt; sg.*,&lt;br /&gt;(&lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=select&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color:#0000FF"&gt;select&lt;/a&gt; &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=top&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color:#0000FF"&gt;top&lt;/a&gt; 1 1 &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=from&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color:#0000FF"&gt;from&lt;/a&gt; section_roster sr &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=where&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color:#0000FF"&gt;where&lt;/a&gt; sr.section_grade_id = sg.section_grade_id) &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=as&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color:#0000FF"&gt;as&lt;/a&gt; isUsed&lt;br /&gt;&lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=from&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color:#0000FF"&gt;from&lt;/a&gt; section_grade sg&lt;br /&gt;&lt;/pre&gt;&lt;/span&gt;&lt;/td&gt;   &lt;/tr&gt;  &lt;/tbody&gt;&lt;/table&gt;I assumed that in the absence of any ordering, "select top 1 1" would be converted by SQL Server into a sort of "exists" statement, and would therefore be the fastest query for the job.  But just out of curiosity, I ran a similar LINQ query in LINQPad to see what SQL would be generated.  Based on those results, I created the following query:&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div id="Panel1" class="OuterPanel"&gt;&lt;div id="OuterPanel" class="CodeViewPanel"&gt;&lt;table id="CodeTable" border="0"&gt;&lt;tbody&gt;   &lt;tr id="Row1"&gt;    &lt;td id="Lines" class="Lines"&gt;&lt;pre&gt;1&lt;br /&gt;2&lt;br /&gt;3&lt;br /&gt;4&lt;br /&gt;5&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td id="SourceCode" class="Code"&gt;&lt;span id="CodeText"&gt;&lt;pre&gt;&lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=select&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color:#0000FF"&gt;select&lt;/a&gt; sg.*,&lt;br /&gt;(&lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=case&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color:#0000FF"&gt;case&lt;/a&gt; &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=when&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color:#0000FF"&gt;when&lt;/a&gt; &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=exists&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color:#0000FF"&gt;exists&lt;/a&gt;(&lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=select&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color:#0000FF"&gt;select&lt;/a&gt; &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=null&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color:#0000FF"&gt;null&lt;/a&gt; &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=from&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color:#0000FF"&gt;from&lt;/a&gt; section_roster sr &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=where&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color:#0000FF"&gt;where&lt;/a&gt; sr.section_grade_id = sg.section_grade_id) &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=then&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color:#0000FF"&gt;then&lt;/a&gt; 1&lt;br /&gt;      &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=else&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color:#0000FF"&gt;else&lt;/a&gt; null&lt;br /&gt;      &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=end&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color:#0000FF"&gt;end&lt;/a&gt;) &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=as&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color:#0000FF"&gt;as&lt;/a&gt; isUsed&lt;br /&gt;&lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=from&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color:#0000FF"&gt;from&lt;/a&gt; section_grade sg&lt;br /&gt;&lt;/pre&gt;&lt;/span&gt;&lt;/td&gt;   &lt;/tr&gt;  &lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;/div&gt;Although it's not as simple a query, I was able to drop the execution time from about 27 milliseconds to about 9 milliseconds.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8924020273529189874-461415429850165137?l=dotnetdom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dotnetdom.blogspot.com/feeds/461415429850165137/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dotnetdom.blogspot.com/2009/05/fastest-way-to-check-for-existence-in.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8924020273529189874/posts/default/461415429850165137'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8924020273529189874/posts/default/461415429850165137'/><link rel='alternate' type='text/html' href='http://dotnetdom.blogspot.com/2009/05/fastest-way-to-check-for-existence-in.html' title='Fastest way to check for existence in a table'/><author><name>J²</name><uri>http://www.blogger.com/profile/14478332251437579476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://photos1.blogger.com/img/268/3041/1024/IMGP17751.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8924020273529189874.post-8990021408219422295</id><published>2009-04-16T11:05:00.000-07:00</published><updated>2009-04-16T15:28:35.476-07:00</updated><title type='text'>Enumerate across a date range in Linq using "yield"</title><content type='html'>I'm making a generic data table displayer which should be able to display any set of data that is formatted properly.  It can either deduce the table headers based on the data it receives, or it can use ones that I specify via a list of key/value pairs.  For example, by setting the value of this property:&lt;div id="Panel1" class="OuterPanel"&gt;&lt;div id="TitlePanel" class="CodeViewTitlePanel"&gt;&lt;div id="InnerTitlePanel" class="CodeTitle"&gt;&lt;span id="TitleText"&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div id="OuterPanel" class="CodeViewPanel"&gt;&lt;table id="CodeTable" border="0"&gt;&lt;tbody&gt;&lt;tr id="Row1"&gt;&lt;td id="Lines" class="Lines"&gt;&lt;pre&gt;1&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td id="SourceCode" class="Code"&gt;&lt;span id="CodeText"&gt;&lt;pre&gt;IEnumerable&amp;lt;DataPair&amp;lt;&lt;span style="color:#0000FF;"&gt;object&lt;/span&gt;, String&amp;gt;&amp;gt; RowKeysWithHeaders&lt;/pre&gt;&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;... I can make the row headers display all of the Strings on the right side of the given DataPairs in the IEnumerable's order, and the data for each row of the table will be aligned to match the keys on the left side of the DataPairs.&lt;/div&gt;&lt;div id="OuterPanel" class="CodeViewPanel"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div id="OuterPanel" class="CodeViewPanel"&gt;Now, let's say I'm using the data returned by the query I mentioned &lt;a href="http://dotnetdom.blogspot.com/2009/04/improved-dynamic-query.html"&gt;yesterday&lt;/a&gt;, which will only include dates for which there are TrackedTime entries, but I want to display all dates within a given date range, and simply leave cells empty if there are no entries for those dates.  Furthermore, I want to specify how the dates are formatted.  I &lt;span class="Apple-style-span" style="font-style: italic;"&gt;could&lt;/span&gt; create a list of date/String pairs to use as row keys with headers, like this:&lt;/div&gt;&lt;/div&gt;&lt;div id="Panel1" class="OuterPanel"&gt;&lt;div id="TitlePanel" class="CodeViewTitlePanel"&gt;&lt;div id="InnerTitlePanel" class="CodeTitle"&gt;&lt;span id="TitleText"&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div id="OuterPanel" class="CodeViewPanel"&gt;&lt;table id="CodeTable" border="0"&gt;&lt;tbody&gt;&lt;tr id="Row1"&gt;&lt;td id="Lines" class="Lines"&gt;&lt;pre&gt;1&lt;br /&gt;2&lt;br /&gt;3&lt;br /&gt;4&lt;br /&gt;5&lt;br /&gt;6&lt;br /&gt;7&lt;br /&gt;8&lt;br /&gt;9&lt;br /&gt;10&lt;br /&gt;11&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td id="SourceCode" class="Code"&gt;&lt;span id="CodeText"&gt;&lt;pre&gt;List&amp;lt;DataPair&amp;lt;&lt;span style="color:#0000FF;"&gt;object&lt;/span&gt;, String&amp;gt;&amp;gt; dateHeaders = &lt;span style="color:#0000FF;"&gt;new&lt;/span&gt; List&amp;lt;DataPair&amp;lt;&lt;span style="color:#0000FF;"&gt;object&lt;/span&gt;, String&amp;gt;&amp;gt;();&lt;br /&gt;&lt;span style="color:#0000FF;"&gt;for&lt;/span&gt;(DateTime date = startDate; date &amp;lt; endDate; date.AddDays(1))&lt;br /&gt;{&lt;br /&gt;   DataPair&amp;lt;&lt;span style="color:#0000FF;"&gt;object&lt;/span&gt;, String&amp;gt; header = &lt;span style="color:#0000FF;"&gt;new&lt;/span&gt; DataPair&amp;lt;&lt;span style="color:#0000FF;"&gt;object&lt;/span&gt;, String&amp;gt;&lt;br /&gt;   {&lt;br /&gt;       LeftObject = date,&lt;br /&gt;       RightObject = date.ToShortDateString()&lt;br /&gt;   };&lt;br /&gt;   dateHeaders.Add(header);&lt;br /&gt;}&lt;br /&gt;&lt;span style="color:#0000FF;"&gt;this&lt;/span&gt;.ReportTableDisplay1.RowKeysWithHeaders = dateHeaders;&lt;/pre&gt;&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;/div&gt;But that would be kind of wasteful, wouldn't it?  It would mean creating an entire List of dates, when all I need is to print a bunch of consecutive dates--something I should be able to do mathematically on the fly.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;A more efficient way would be to create an IEnumerable class (and an accompanying IEnumerator class) that know how to iterate across dates.  But that's a lot more work and a lot more code for something that should be relatively simple.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Thanks to the &lt;span class="Apple-style-span" style="font-style: italic;"&gt;yield&lt;/span&gt; operator, there is a better way.  This simple method:&lt;/div&gt;&lt;div id="Panel1" class="OuterPanel"&gt;&lt;div id="TitlePanel" class="CodeViewTitlePanel"&gt;&lt;div id="InnerTitlePanel" class="CodeTitle"&gt;&lt;span id="TitleText"&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div id="OuterPanel" class="CodeViewPanel"&gt;&lt;table id="CodeTable" border="0"&gt;&lt;tbody&gt;&lt;tr id="Row1"&gt;&lt;td id="Lines" class="Lines"&gt;&lt;pre&gt;1&lt;br /&gt;2&lt;br /&gt;3&lt;br /&gt;4&lt;br /&gt;5&lt;br /&gt;6&lt;br /&gt;7&lt;br /&gt;8&lt;br /&gt;9&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td id="SourceCode" class="Code"&gt;&lt;span id="CodeText"&gt;&lt;pre&gt;&lt;span style="color:#0000FF;"&gt;public &lt;/span&gt;&lt;span style="color:#0000FF;"&gt;static&lt;/span&gt; IEnumerable&amp;lt;DateTime&amp;gt; DaysInRange(DateTime startDate, DateTime endDate)&lt;br /&gt;{&lt;br /&gt;   DateTime current = startDate;&lt;br /&gt;&lt;span style="color:#0000FF;"&gt;    while&lt;/span&gt; (current &amp;lt;= endDate)&lt;br /&gt;   {&lt;br /&gt;       yield &lt;span style="color:#0000FF;"&gt;return&lt;/span&gt; current;&lt;br /&gt;       current = current.AddDays(1);&lt;br /&gt;   }&lt;br /&gt;}&lt;/pre&gt;&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;/div&gt;... will create an enumerable object that does exactly what I need it to, without the need for any extra classes or anything.  Here's how I use it:&lt;div&gt;&lt;div id="Panel1" class="OuterPanel"&gt;&lt;div id="TitlePanel" class="CodeViewTitlePanel"&gt;&lt;div id="InnerTitlePanel" class="CodeTitle"&gt;&lt;span id="TitleText"&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div id="OuterPanel" class="CodeViewPanel"&gt;&lt;table id="CodeTable" border="0"&gt;&lt;tbody&gt;&lt;tr id="Row1"&gt;&lt;td id="Lines" class="Lines"&gt;&lt;pre&gt;1&lt;br /&gt;2&lt;br /&gt;3&lt;br /&gt;4&lt;br /&gt;5&lt;br /&gt;6&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td id="SourceCode" class="Code"&gt;&lt;span id="CodeText"&gt;&lt;pre&gt;&lt;span style="color:#0000FF;"&gt;this&lt;/span&gt;.ReportTableDisplay1.RowKeysWithHeaders = from d &lt;span style="color:#0000FF;"&gt;in&lt;/span&gt; DaysInRange(startDate, endDate)&lt;br /&gt;                                             select &lt;span style="color:#0000FF;"&gt;new&lt;/span&gt; DataPair&amp;lt;&lt;span style="color:#0000FF;"&gt;object&lt;/span&gt;, String&amp;gt;&lt;br /&gt;                                             {&lt;br /&gt;                                                 LeftObject = d,&lt;br /&gt;                                                 RightObject = d.ToShortDateString()&lt;br /&gt;                                             };&lt;/pre&gt;&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;This simple LINQ statement then gives me an IEnumerable that iteratively creates new DatePairs &lt;span class="Apple-style-span" style="font-style: italic;"&gt;as the program traverses it&lt;/span&gt;.  You have to admit, that's pretty smooth.  That means that if I decide to paginate the table results, I can use the Take() method, and the system won't even produce DataPairs for dates that I don't iterate over.  I can also move my DaysInRange method into a common utility class where it can be accessed any time I need to traverse a range of dates.  It's a great example of how we can use LINQ in conjunction with the &lt;span class="Apple-style-span" style="font-style: italic;"&gt;yield&lt;/span&gt; operator to create simple, efficient code.&lt;/div&gt;&lt;div id="OuterPanel" class="CodeViewPanel"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div id="OuterPanel" class="CodeViewPanel"&gt;It can also be used to highlight one of the dangers of accepting IEnumerable arguments.  Since I literally have no idea how expensive it might be to iterate over a given IEnumerable, I need to make sure my ReportTableDisplay class only iterates over the RowKeysWithHeaders once.  Otherwise I could end up creating who-knows-how-many copies of exactly the same DataPair without even realizing it.  Just think how that would turn out if I was using a truly expensive IEnumerable--one whose IEnumerator begins by accessing data from over the Internet, for example!&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8924020273529189874-8990021408219422295?l=dotnetdom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dotnetdom.blogspot.com/feeds/8990021408219422295/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dotnetdom.blogspot.com/2009/04/enumerate-across-date-range-in-linq.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8924020273529189874/posts/default/8990021408219422295'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8924020273529189874/posts/default/8990021408219422295'/><link rel='alternate' type='text/html' href='http://dotnetdom.blogspot.com/2009/04/enumerate-across-date-range-in-linq.html' title='Enumerate across a date range in Linq using &quot;yield&quot;'/><author><name>J²</name><uri>http://www.blogger.com/profile/14478332251437579476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://photos1.blogger.com/img/268/3041/1024/IMGP17751.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8924020273529189874.post-9041325962475329147</id><published>2009-04-15T14:53:00.000-07:00</published><updated>2009-04-15T15:35:30.146-07:00</updated><title type='text'>Improved Dynamic Query</title><content type='html'>&lt;a href="http://dotnetdom.blogspot.com/2009/04/dynamic-queries-in-entity-framework.html"&gt;Yesterday&lt;/a&gt; I figured out how we could use C# Expressions to filter query results by any number of criteria.  Today I refined my approach somewhat.  Instead of the long, complex LINQ query I used there, I now have:&lt;div id="Panel1" class="OuterPanel"&gt;&lt;div id="OuterPanel" class="CodeViewPanel"&gt;&lt;table id="CodeTable" border="0"&gt;   &lt;tbody&gt;&lt;tr id="Row1"&gt;&lt;br /&gt;    &lt;td id="Lines" class="Lines"&gt;&lt;pre&gt;1&lt;br /&gt;2&lt;br /&gt;3&lt;br /&gt;4&lt;br /&gt;5&lt;br /&gt;6&lt;br /&gt;7&lt;br /&gt;8&lt;br /&gt;9&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td id="SourceCode" class="Code"&gt;&lt;span id="CodeText"&gt;&lt;pre&gt;var userTimes = (from t &lt;span style="color: rgb(0, 0, 255);"&gt;in&lt;/span&gt; times&lt;br /&gt;  group t by &lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; {t.User.UserName, t.TargetDate} into ut&lt;br /&gt;  select &lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt;&lt;br /&gt;  {&lt;br /&gt;   UserName = ut.Key.UserName,&lt;br /&gt;  TargetDate = ut.Key.TargetDate,&lt;br /&gt;  Minutes = ut.Sum(t =&amp;gt; t.Minutes)&lt;br /&gt;  }&lt;br /&gt;  );&lt;br /&gt;&lt;/pre&gt;&lt;/span&gt;&lt;/td&gt;&lt;br /&gt;   &lt;/tr&gt;  &lt;/tbody&gt;&lt;/table&gt;This produces a faster, more reasonable set of SQL code which returns almost identical data:&lt;/div&gt;&lt;/div&gt;&lt;div id="Panel1" class="OuterPanel"&gt;&lt;div id="OuterPanel" class="CodeViewPanel"&gt;&lt;table id="CodeTable" border="0"&gt;   &lt;tbody&gt;&lt;tr id="Row1"&gt;&lt;br /&gt;    &lt;td id="Lines" class="Lines"&gt;&lt;pre&gt;1&lt;br /&gt;2&lt;br /&gt;3&lt;br /&gt;4&lt;br /&gt;5&lt;br /&gt;6&lt;br /&gt;7&lt;br /&gt;8&lt;br /&gt;9&lt;br /&gt;10&lt;br /&gt;11&lt;br /&gt;12&lt;br /&gt;13&lt;br /&gt;14&lt;br /&gt;15&lt;br /&gt;16&lt;br /&gt;17&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td id="SourceCode" class="Code"&gt;&lt;span id="CodeText"&gt;&lt;pre&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;-- Region Parameters&lt;/span&gt;&lt;br /&gt;&lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=DECLARE&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;DECLARE&lt;/a&gt; @p__linq__2 &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=DateTime&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;DateTime&lt;/a&gt; &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=SET&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;SET&lt;/a&gt; @p__linq__2 = '&lt;span style="color: rgb(139, 0, 0);"&gt;2009-02-14 16:01:50.069&lt;/span&gt;'&lt;br /&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;-- EndRegion&lt;/span&gt;&lt;br /&gt;&lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=SELECT&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;SELECT&lt;/a&gt;&lt;br /&gt;1 &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=AS&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;AS&lt;/a&gt; [C1],&lt;br /&gt;[GroupBy1].[K2] &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=AS&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;AS&lt;/a&gt; [UserName],&lt;br /&gt;[GroupBy1].[K1] &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=AS&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;AS&lt;/a&gt; [TargetDate],&lt;br /&gt;[GroupBy1].[A1] &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=AS&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;AS&lt;/a&gt; [C2]&lt;br /&gt;&lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=FROM&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;FROM&lt;/a&gt; ( &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=SELECT&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;SELECT&lt;/a&gt;&lt;br /&gt; [Extent1].[TargetDate] &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=AS&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;AS&lt;/a&gt; [K1],&lt;br /&gt; [Extent2].[UserName] &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=AS&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;AS&lt;/a&gt; [K2],&lt;br /&gt; &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=SUM&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;SUM&lt;/a&gt;( &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=CAST&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;CAST&lt;/a&gt;( [Extent1].[Minutes] &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=AS&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;AS&lt;/a&gt; &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=int&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;int&lt;/a&gt;)) &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=AS&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;AS&lt;/a&gt; [A1]&lt;br /&gt; &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=FROM&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;FROM&lt;/a&gt;  [dbo].[TrackedTime] &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=AS&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;AS&lt;/a&gt; [Extent1]&lt;br /&gt; &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=LEFT&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;LEFT&lt;/a&gt; &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=OUTER&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;OUTER&lt;/a&gt; &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=JOIN&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;JOIN&lt;/a&gt; [dbo].[aspnet_Users] &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=AS&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;AS&lt;/a&gt; [Extent2] &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=ON&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;ON&lt;/a&gt; [Extent1].[UserId] = [Extent2].[UserId]&lt;br /&gt; &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=WHERE&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;WHERE&lt;/a&gt; ([Extent1].[TargetDate] &amp;gt; @p__linq__2) &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=AND&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;AND&lt;/a&gt; ([Extent1].[TargetDate] &amp;lt; (GetDate()))&lt;br /&gt; &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=GROUP&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;GROUP&lt;/a&gt; &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=BY&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;BY&lt;/a&gt; [Extent1].[TargetDate], [Extent2].[UserName]&lt;br /&gt;)  &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=AS&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;AS&lt;/a&gt; [GroupBy1]&lt;br /&gt;&lt;/pre&gt;&lt;/span&gt;&lt;/td&gt;&lt;br /&gt;   &lt;/tr&gt;  &lt;/tbody&gt;&lt;/table&gt;Note that I avoided the problem I mentioned &lt;a href="http://dotnetdom.blogspot.com/2009/02/joining-entities-using-new-operator.html"&gt;here&lt;/a&gt; by returning a simple set of native types rather than Entity Framework objects.  This approach wouldn't be best under normal circumstances.  If I'm querying the database for usernames, for example, I will often want to have more user data as well (like their real names) available to my front-end code.  In that case, I could benefit from using the Entity Framework to get all the object data in a single roundtrip.  However, if I'm pulling data for reporting purposes, I generally know exactly what data I want to be displaying.  In that case it's more important to keep the data set small and fast.  I've seen poorly-designed reporting engines pull so much data from the database that the VM runs out of memory, which causes all sorts of problems.&lt;br /&gt;&lt;br /&gt;Finally, rather than relying on the LINQ framework to package my objects into custom classes for me, I created a generic TableData class, along with an extender that allows me to do this:&lt;table id="CodeTable" border="0"&gt;   &lt;tbody&gt;&lt;tr id="Row1"&gt;&lt;br /&gt;    &lt;td id="Lines" class="Lines"&gt;&lt;pre&gt;1&lt;br /&gt;2&lt;br /&gt;3&lt;br /&gt;4&lt;br /&gt;5&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td id="SourceCode" class="Code"&gt;&lt;span id="CodeText"&gt;&lt;pre&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; TableData&amp;lt;String, DateTime, &lt;span style="color: rgb(0, 0, 255);"&gt;int&lt;/span&gt;&amp;gt; generateData(List&amp;lt;Filter&amp;lt;TrackedTime&amp;gt;&amp;gt; dateFilters)&lt;br /&gt;{&lt;br /&gt; ...&lt;br /&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt; userTimes.ToTable(d =&amp;gt; d.UserName, d =&amp;gt; d.TargetDate, d =&amp;gt; d.Minutes);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/span&gt;&lt;/td&gt;&lt;br /&gt;   &lt;/tr&gt;  &lt;/tbody&gt;&lt;/table&gt;The next step would be to create a generic web control that creates a front-end table when given the returned report data.  That way we can use a single control to display all kinds of report data, rather than creating a new method to display each new set of report data.&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8924020273529189874-9041325962475329147?l=dotnetdom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dotnetdom.blogspot.com/feeds/9041325962475329147/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dotnetdom.blogspot.com/2009/04/improved-dynamic-query.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8924020273529189874/posts/default/9041325962475329147'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8924020273529189874/posts/default/9041325962475329147'/><link rel='alternate' type='text/html' href='http://dotnetdom.blogspot.com/2009/04/improved-dynamic-query.html' title='Improved Dynamic Query'/><author><name>J²</name><uri>http://www.blogger.com/profile/14478332251437579476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://photos1.blogger.com/img/268/3041/1024/IMGP17751.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8924020273529189874.post-414108036456277386</id><published>2009-04-14T17:19:00.000-07:00</published><updated>2009-04-14T17:35:40.952-07:00</updated><title type='text'>Dynamic Queries in Entity Framework</title><content type='html'>I've been working on a proof-of-concept for building dynamic Linq queries in the Entity Framework.  The idea is to have any number of criteria that a user can set to limit or expand the scope of (for example) a report.&lt;br /&gt;&lt;br /&gt;I still have a long way to go before it would be ready to use for real, but here's what I've been able to do:&lt;br /&gt;&lt;div id="Panel1" class="OuterPanel"&gt;&lt;div id="OuterPanel" class="CodeViewPanel"&gt;&lt;table id="CodeTable" border="0"&gt;   &lt;tbody&gt;&lt;tr id="Row1"&gt;&lt;br /&gt;    &lt;td id="Lines" class="Lines"&gt;&lt;pre&gt;1&lt;br /&gt;2&lt;br /&gt;3&lt;br /&gt;4&lt;br /&gt;5&lt;br /&gt;6&lt;br /&gt;7&lt;br /&gt;8&lt;br /&gt;9&lt;br /&gt;10&lt;br /&gt;11&lt;br /&gt;12&lt;br /&gt;13&lt;br /&gt;14&lt;br /&gt;15&lt;br /&gt;16&lt;br /&gt;17&lt;br /&gt;18&lt;br /&gt;19&lt;br /&gt;20&lt;br /&gt;21&lt;br /&gt;22&lt;br /&gt;23&lt;br /&gt;24&lt;br /&gt;25&lt;br /&gt;26&lt;br /&gt;27&lt;br /&gt;28&lt;br /&gt;29&lt;br /&gt;30&lt;br /&gt;31&lt;br /&gt;32&lt;br /&gt;33&lt;br /&gt;34&lt;br /&gt;35&lt;br /&gt;36&lt;br /&gt;37&lt;br /&gt;38&lt;br /&gt;39&lt;br /&gt;40&lt;br /&gt;41&lt;br /&gt;42&lt;br /&gt;43&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td id="SourceCode" class="Code"&gt;&lt;span id="CodeText"&gt;&lt;pre&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;class&lt;/span&gt; ReportPerUserPerDay2&lt;br /&gt;  {&lt;br /&gt;      &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; List&amp;lt;UserNamesWithDatesWithMinuteTotals&amp;gt; generateData(List&amp;lt;Filter&amp;lt;TrackedTime&amp;gt;&amp;gt; dateFilters)&lt;br /&gt;      {&lt;br /&gt;          TimesheetEntities context = &lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; TimesheetEntities();&lt;br /&gt;          IQueryable&amp;lt;TrackedTime&amp;gt; times = context.TrackedTime;&lt;br /&gt;          &lt;span style="color: rgb(0, 0, 255);"&gt;foreach&lt;/span&gt; (Filter&amp;lt;TrackedTime&amp;gt; dateFilter &lt;span style="color: rgb(0, 0, 255);"&gt;in&lt;/span&gt; dateFilters)&lt;br /&gt;          {&lt;br /&gt;              times = times.Where(dateFilter.getPredicate());&lt;br /&gt;          }&lt;br /&gt;          var userTimes = (from t &lt;span style="color: rgb(0, 0, 255);"&gt;in&lt;/span&gt; times&lt;br /&gt;                           group t by t.User.UserName into ut&lt;br /&gt;                           from ut2 &lt;span style="color: rgb(0, 0, 255);"&gt;in&lt;/span&gt;&lt;br /&gt;                               (from t &lt;span style="color: rgb(0, 0, 255);"&gt;in&lt;/span&gt; ut&lt;br /&gt;                                group t by t.TargetDate into ut3&lt;br /&gt;                                select &lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; DatesWithMinuteTotals()&lt;br /&gt;                                {&lt;br /&gt;                                    TargetDate = ut3.Key,&lt;br /&gt;                                    Minutes = ut3.Sum(t =&amp;gt; t.Minutes)&lt;br /&gt;                                })&lt;br /&gt;                           group ut2 by ut.Key into ut4&lt;br /&gt;                           select &lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; UserNamesWithDatesWithMinuteTotals()&lt;br /&gt;                           {&lt;br /&gt;                               UserName = ut4.Key,&lt;br /&gt;                               Dates = from t &lt;span style="color: rgb(0, 0, 255);"&gt;in&lt;/span&gt; ut4 select t&lt;br /&gt;                           }&lt;br /&gt;               );&lt;br /&gt;        &lt;br /&gt;          &lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt; userTimes.ToList();&lt;br /&gt;      }&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;class&lt;/span&gt; DatesWithMinuteTotals&lt;br /&gt;  {&lt;br /&gt;      &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; DateTime TargetDate;&lt;br /&gt;      &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;long&lt;/span&gt; Minutes;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;class&lt;/span&gt; UserNamesWithDatesWithMinuteTotals&lt;br /&gt;  {&lt;br /&gt;      &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; String UserName;&lt;br /&gt;      &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; IEnumerable&amp;lt;DatesWithMinuteTotals&amp;gt; Dates;&lt;br /&gt;  }&lt;/pre&gt;&lt;/span&gt;&lt;/td&gt;&lt;br /&gt;   &lt;/tr&gt;  &lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;/div&gt;So I can pass the generateData method filters like this one:&lt;br /&gt;       &lt;div id="Panel1" class="OuterPanel"&gt;&lt;div id="OuterPanel" class="CodeViewPanel"&gt;&lt;table id="CodeTable" border="0"&gt;   &lt;tbody&gt;&lt;tr id="Row1"&gt;&lt;br /&gt;    &lt;td id="Lines" class="Lines"&gt;&lt;pre&gt;1&lt;br /&gt;2&lt;br /&gt;3&lt;br /&gt;4&lt;br /&gt;5&lt;br /&gt;6&lt;br /&gt;7&lt;br /&gt;8&lt;br /&gt;9&lt;br /&gt;10&lt;br /&gt;11&lt;br /&gt;12&lt;br /&gt;13&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td id="SourceCode" class="Code"&gt;&lt;span id="CodeText"&gt;&lt;pre&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; partial &lt;span style="color: rgb(0, 0, 255);"&gt;class&lt;/span&gt; Controls_ReportFilters_FilterDateRange : System.Web.UI.UserControl, TimesheetReporting.Filters.Filter&amp;lt;TrackedTime&amp;gt;&lt;br /&gt;{&lt;br /&gt;   ...&lt;br /&gt;&lt;br /&gt;   &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; Expression&amp;lt;Func&amp;lt;TrackedTime, &lt;span style="color: rgb(0, 0, 255);"&gt;bool&lt;/span&gt;&amp;gt;&amp;gt; getPredicate()&lt;br /&gt;   {&lt;br /&gt;       &lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt; (StartDate.Ticks == 0 &amp;amp;&amp;amp; EndDate.Ticks == 0) &lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt; t =&amp;gt; &lt;span style="color: rgb(0, 0, 255);"&gt;true&lt;/span&gt;;&lt;br /&gt;       &lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt; (StartDate.Ticks == 0) &lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt; t =&amp;gt; t.TargetDate &amp;lt;= EndDate;&lt;br /&gt;       &lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt; (EndDate.Ticks == 0) &lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt; t =&amp;gt; t.TargetDate &amp;gt;= StartDate;&lt;br /&gt;       &lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt; t =&amp;gt; t.TargetDate &amp;lt;= EndDate &amp;amp;&amp;amp; t.TargetDate &amp;gt;= StartDate;&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/span&gt;&lt;/td&gt;&lt;br /&gt;   &lt;/tr&gt;&lt;br /&gt;  &lt;/tbody&gt;&lt;/table&gt;and the Linq statement will auto-generate this crazy SQL code:&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div id="Panel1" class="OuterPanel"&gt;&lt;div id="OuterPanel" class="CodeViewPanel"&gt;          &lt;table id="CodeTable" border="0"&gt;   &lt;tbody&gt;&lt;tr id="Row1"&gt;&lt;br /&gt;    &lt;td id="Lines" class="Lines"&gt;&lt;pre&gt;1&lt;br /&gt;2&lt;br /&gt;3&lt;br /&gt;4&lt;br /&gt;5&lt;br /&gt;6&lt;br /&gt;7&lt;br /&gt;8&lt;br /&gt;9&lt;br /&gt;10&lt;br /&gt;11&lt;br /&gt;12&lt;br /&gt;13&lt;br /&gt;14&lt;br /&gt;15&lt;br /&gt;16&lt;br /&gt;17&lt;br /&gt;18&lt;br /&gt;19&lt;br /&gt;20&lt;br /&gt;21&lt;br /&gt;22&lt;br /&gt;23&lt;br /&gt;24&lt;br /&gt;25&lt;br /&gt;26&lt;br /&gt;27&lt;br /&gt;28&lt;br /&gt;29&lt;br /&gt;30&lt;br /&gt;31&lt;br /&gt;32&lt;br /&gt;33&lt;br /&gt;34&lt;br /&gt;35&lt;br /&gt;36&lt;br /&gt;37&lt;br /&gt;38&lt;br /&gt;39&lt;br /&gt;40&lt;br /&gt;41&lt;br /&gt;42&lt;br /&gt;43&lt;br /&gt;44&lt;br /&gt;45&lt;br /&gt;46&lt;br /&gt;47&lt;br /&gt;48&lt;br /&gt;49&lt;br /&gt;50&lt;br /&gt;51&lt;br /&gt;52&lt;br /&gt;53&lt;br /&gt;54&lt;br /&gt;55&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td id="SourceCode" class="Code"&gt;&lt;span id="CodeText"&gt;&lt;pre&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;-- Region Parameters&lt;/span&gt;&lt;br /&gt;&lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=DECLARE&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;DECLARE&lt;/a&gt; p__linq__2 &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=DateTime&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;DateTime&lt;/a&gt; &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=SET&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;SET&lt;/a&gt; p__linq__2 = '&lt;span style="color: rgb(139, 0, 0);"&gt;2009-02-13 18:13:53.470&lt;/span&gt;'&lt;br /&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;-- EndRegion&lt;/span&gt;&lt;br /&gt;&lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=SELECT&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;SELECT&lt;/a&gt;&lt;br /&gt;[Project7].[UserName] &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=AS&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;AS&lt;/a&gt; [UserName],&lt;br /&gt;[Project7].[C1] &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=AS&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;AS&lt;/a&gt; [C1],&lt;br /&gt;[Project7].[C3] &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=AS&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;AS&lt;/a&gt; [C2],&lt;br /&gt;[Project7].[TargetDate] &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=AS&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;AS&lt;/a&gt; [TargetDate],&lt;br /&gt;[Project7].[C2] &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=AS&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;AS&lt;/a&gt; [C3]&lt;br /&gt;&lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=FROM&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;FROM&lt;/a&gt; ( &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=SELECT&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;SELECT&lt;/a&gt;&lt;br /&gt; [&lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=Distinct&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;Distinct&lt;/a&gt;2].[UserName] &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=AS&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;AS&lt;/a&gt; [UserName],&lt;br /&gt; 1 &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=AS&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;AS&lt;/a&gt; [C1],&lt;br /&gt; [Project6].[TargetDate] &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=AS&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;AS&lt;/a&gt; [TargetDate],&lt;br /&gt; &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=CASE&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;CASE&lt;/a&gt; &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=WHEN&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;WHEN&lt;/a&gt; ([Project6].[C2] &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=IS&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;IS&lt;/a&gt; &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=NULL&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;NULL&lt;/a&gt;) &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=THEN&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;THEN&lt;/a&gt; &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=CAST&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;CAST&lt;/a&gt;(&lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=NULL&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;NULL&lt;/a&gt; &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=AS&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;AS&lt;/a&gt; &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=bigint&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;bigint&lt;/a&gt;) &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=ELSE&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;ELSE&lt;/a&gt;  &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=CAST&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;CAST&lt;/a&gt;( [Project6].[C1] &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=AS&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;AS&lt;/a&gt; &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=bigint&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;bigint&lt;/a&gt;) &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=END&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;END&lt;/a&gt; &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=AS&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;AS&lt;/a&gt; [C2],&lt;br /&gt; [Project6].[C2] &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=AS&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;AS&lt;/a&gt; [C3]&lt;br /&gt; &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=FROM&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;FROM&lt;/a&gt;   (&lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=SELECT&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;SELECT&lt;/a&gt; &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=DISTINCT&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;DISTINCT&lt;/a&gt;&lt;br /&gt;  [Project2].[UserName] &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=AS&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;AS&lt;/a&gt; [UserName]&lt;br /&gt;  &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=FROM&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;FROM&lt;/a&gt;   (&lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=SELECT&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;SELECT&lt;/a&gt;&lt;br /&gt;   @p__linq__2 &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=AS&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;AS&lt;/a&gt; [p__linq__2],&lt;br /&gt;   [&lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=Distinct&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;Distinct&lt;/a&gt;1].[UserName] &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=AS&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;AS&lt;/a&gt; [UserName]&lt;br /&gt;   &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=FROM&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;FROM&lt;/a&gt; ( &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=SELECT&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;SELECT&lt;/a&gt; &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=DISTINCT&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;DISTINCT&lt;/a&gt;&lt;br /&gt;    [Extent2].[UserName] &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=AS&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;AS&lt;/a&gt; [UserName]&lt;br /&gt;    &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=FROM&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;FROM&lt;/a&gt;  [dbo].[TrackedTime] &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=AS&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;AS&lt;/a&gt; [Extent1]&lt;br /&gt;    &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=LEFT&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;LEFT&lt;/a&gt; &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=OUTER&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;OUTER&lt;/a&gt; &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=JOIN&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;JOIN&lt;/a&gt; [dbo].[aspnet_Users] &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=AS&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;AS&lt;/a&gt; [Extent2] &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=ON&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;ON&lt;/a&gt; [Extent1].[UserId] = [Extent2].[UserId]&lt;br /&gt;    &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=WHERE&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;WHERE&lt;/a&gt; [Extent1].[TargetDate] &amp;gt; @p__linq__2&lt;br /&gt;   )  &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=AS&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;AS&lt;/a&gt; [&lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=Distinct&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;Distinct&lt;/a&gt;1] ) &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=AS&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;AS&lt;/a&gt; [Project2]&lt;br /&gt;  &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=CROSS&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;CROSS&lt;/a&gt; APPLY  (&lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=SELECT&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;SELECT&lt;/a&gt;&lt;br /&gt;   [Extent3].[TargetDate] &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=AS&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;AS&lt;/a&gt; [K1]&lt;br /&gt;   &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=FROM&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;FROM&lt;/a&gt;  [dbo].[TrackedTime] &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=AS&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;AS&lt;/a&gt; [Extent3]&lt;br /&gt;   &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=LEFT&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;LEFT&lt;/a&gt; &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=OUTER&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;OUTER&lt;/a&gt; &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=JOIN&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;JOIN&lt;/a&gt; [dbo].[aspnet_Users] &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=AS&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;AS&lt;/a&gt; [Extent4] &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=ON&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;ON&lt;/a&gt; [Extent3].[UserId] = [Extent4].[UserId]&lt;br /&gt;   &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=WHERE&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;WHERE&lt;/a&gt; ([Extent3].[TargetDate] &amp;gt; @p__linq__2) &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=AND&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;AND&lt;/a&gt; (([Extent4].[UserName] = [Project2].[UserName]) &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=OR&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;OR&lt;/a&gt; (([Extent4].[UserName] &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=IS&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;IS&lt;/a&gt; &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=NULL&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;NULL&lt;/a&gt;) &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=AND&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;AND&lt;/a&gt; ([Project2].[UserName] &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=IS&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;IS&lt;/a&gt; &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=NULL&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;NULL&lt;/a&gt;)))&lt;br /&gt;   &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=GROUP&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;GROUP&lt;/a&gt; &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=BY&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;BY&lt;/a&gt; [Extent3].[TargetDate] ) &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=AS&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;AS&lt;/a&gt; [GroupBy1] ) &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=AS&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;AS&lt;/a&gt; [&lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=Distinct&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;Distinct&lt;/a&gt;2]&lt;br /&gt; &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=LEFT&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;LEFT&lt;/a&gt; &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=OUTER&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;OUTER&lt;/a&gt; &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=JOIN&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;JOIN&lt;/a&gt;  (&lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=SELECT&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;SELECT&lt;/a&gt;&lt;br /&gt;  [Project5].[UserName] &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=AS&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;AS&lt;/a&gt; [UserName],&lt;br /&gt;  [GroupBy2].[K1] &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=AS&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;AS&lt;/a&gt; [TargetDate],&lt;br /&gt;  [GroupBy2].[A1] &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=AS&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;AS&lt;/a&gt; [C1],&lt;br /&gt;  1 &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=AS&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;AS&lt;/a&gt; [C2]&lt;br /&gt;  &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=FROM&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;FROM&lt;/a&gt;   (&lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=SELECT&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;SELECT&lt;/a&gt;&lt;br /&gt;   @p__linq__2 &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=AS&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;AS&lt;/a&gt; [p__linq__2],&lt;br /&gt;   [&lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=Distinct&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;Distinct&lt;/a&gt;3].[UserName] &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=AS&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;AS&lt;/a&gt; [UserName]&lt;br /&gt;   &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=FROM&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;FROM&lt;/a&gt; ( &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=SELECT&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;SELECT&lt;/a&gt; &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=DISTINCT&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;DISTINCT&lt;/a&gt;&lt;br /&gt;    [Extent6].[UserName] &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=AS&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;AS&lt;/a&gt; [UserName]&lt;br /&gt;    &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=FROM&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;FROM&lt;/a&gt;  [dbo].[TrackedTime] &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=AS&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;AS&lt;/a&gt; [Extent5]&lt;br /&gt;    &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=LEFT&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;LEFT&lt;/a&gt; &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=OUTER&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;OUTER&lt;/a&gt; &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=JOIN&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;JOIN&lt;/a&gt; [dbo].[aspnet_Users] &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=AS&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;AS&lt;/a&gt; [Extent6] &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=ON&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;ON&lt;/a&gt; [Extent5].[UserId] = [Extent6].[UserId]&lt;br /&gt;    &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=WHERE&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;WHERE&lt;/a&gt; [Extent5].[TargetDate] &amp;gt; @p__linq__2&lt;br /&gt;   )  &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=AS&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;AS&lt;/a&gt; [&lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=Distinct&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;Distinct&lt;/a&gt;3] ) &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=AS&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;AS&lt;/a&gt; [Project5]&lt;br /&gt;  &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=CROSS&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;CROSS&lt;/a&gt; APPLY  (&lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=SELECT&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;SELECT&lt;/a&gt;&lt;br /&gt;   [Extent7].[TargetDate] &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=AS&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;AS&lt;/a&gt; [K1],&lt;br /&gt;   &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=SUM&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;SUM&lt;/a&gt;( &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=CAST&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;CAST&lt;/a&gt;( [Extent7].[Minutes] &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=AS&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;AS&lt;/a&gt; &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=int&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;int&lt;/a&gt;)) &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=AS&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;AS&lt;/a&gt; [A1]&lt;br /&gt;   &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=FROM&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;FROM&lt;/a&gt;  [dbo].[TrackedTime] &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=AS&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;AS&lt;/a&gt; [Extent7]&lt;br /&gt;   &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=LEFT&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;LEFT&lt;/a&gt; &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=OUTER&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;OUTER&lt;/a&gt; &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=JOIN&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;JOIN&lt;/a&gt; [dbo].[aspnet_Users] &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=AS&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;AS&lt;/a&gt; [Extent8] &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=ON&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;ON&lt;/a&gt; [Extent7].[UserId] = [Extent8].[UserId]&lt;br /&gt;   &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=WHERE&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;WHERE&lt;/a&gt; ([Extent7].[TargetDate] &amp;gt; @p__linq__2) &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=AND&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;AND&lt;/a&gt; (([Extent8].[UserName] = [Project5].[UserName]) &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=OR&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;OR&lt;/a&gt; (([Extent8].[UserName] &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=IS&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;IS&lt;/a&gt; &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=NULL&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;NULL&lt;/a&gt;) &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=AND&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;AND&lt;/a&gt; ([Project5].[UserName] &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=IS&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;IS&lt;/a&gt; &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=NULL&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;NULL&lt;/a&gt;)))&lt;br /&gt;   &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=GROUP&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;GROUP&lt;/a&gt; &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=BY&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;BY&lt;/a&gt; [Extent7].[TargetDate] ) &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=AS&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;AS&lt;/a&gt; [GroupBy2] ) &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=AS&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;AS&lt;/a&gt; [Project6] &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=ON&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;ON&lt;/a&gt; ([Project6].[UserName] = [&lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=Distinct&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;Distinct&lt;/a&gt;2].[UserName]) &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=OR&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;OR&lt;/a&gt; (([Project6].[UserName] &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=IS&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;IS&lt;/a&gt; &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=NULL&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;NULL&lt;/a&gt;) &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=AND&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;AND&lt;/a&gt; ([&lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=Distinct&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;Distinct&lt;/a&gt;2].[UserName] &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=IS&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;IS&lt;/a&gt; &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=NULL&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;NULL&lt;/a&gt;))&lt;br /&gt;)  &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=AS&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;AS&lt;/a&gt; [Project7]&lt;br /&gt;&lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=ORDER&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;ORDER&lt;/a&gt; &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=BY&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;BY&lt;/a&gt; [Project7].[UserName] &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=ASC&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;ASC&lt;/a&gt;, [Project7].[C3] &lt;a href="http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=ASC&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99" style="color: rgb(0, 0, 255);"&gt;ASC&lt;/a&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/span&gt;&lt;/td&gt;&lt;br /&gt;   &lt;/tr&gt;&lt;br /&gt;  &lt;/tbody&gt;&lt;/table&gt;which, amazingly enough, rather efficiently produces exactly the information I wanted, and no more.  Pretty slick, eh?&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8924020273529189874-414108036456277386?l=dotnetdom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dotnetdom.blogspot.com/feeds/414108036456277386/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dotnetdom.blogspot.com/2009/04/dynamic-queries-in-entity-framework.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8924020273529189874/posts/default/414108036456277386'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8924020273529189874/posts/default/414108036456277386'/><link rel='alternate' type='text/html' href='http://dotnetdom.blogspot.com/2009/04/dynamic-queries-in-entity-framework.html' title='Dynamic Queries in Entity Framework'/><author><name>J²</name><uri>http://www.blogger.com/profile/14478332251437579476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://photos1.blogger.com/img/268/3041/1024/IMGP17751.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8924020273529189874.post-40714889101588553</id><published>2009-02-19T12:24:00.000-08:00</published><updated>2009-02-19T12:53:05.000-08:00</updated><title type='text'>LinqPad, my new favorite tool</title><content type='html'>As I was looking into LINQ, I found a tool called &lt;a href="http://www.linqpad.net/"&gt;LINQPad&lt;/a&gt;, which allows you to run LINQ queries on a typical SQL database.  "Cool," I thought, "That might help me become familiar with LINQ syntax."  I had no idea of the power of this tool.&lt;br /&gt;&lt;br /&gt;When it first connects to your chosen database, LINQPad automatically generates a data-object mapping based on the foreign and primary keys in your database.  So rather than having to worry about doing an INNER JOIN ON table1.some_column = table2.some_column, you can just use standard LINQ syntax to join the objects based on their relationships.  Another advantage is that it provides links from one table to another, so you can easily jump around the table structure, seeing how things are interconnected.&lt;br /&gt;&lt;br /&gt;Visualization of the returned data is much more intuitive and powerful than the simple grid that is returned by normal applications.  For example, using the "select new" statement I discussed in my last posting, you can see lists of objects &lt;span style="font-style: italic;"&gt;grouped within &lt;/span&gt;other objects, fully collapsible and everything!  For this reason, I prefer it to SQL Server Management Studio for viewing information in the database.&lt;br /&gt;&lt;br /&gt;LINQPad also lets you see what code is generated based on the LINQ queries you put in.  You can see the Lambda code, the SQL code, and even the Instruction Language code that comes from the statements you write.  That's very handy for understanding the performance of your code.&lt;br /&gt;&lt;br /&gt;LINQPad's uses aren't limited to Linq to SQL, however!  You can reference the .dll file from your Entity Framework data layer and run queries as if you were writing code right within Visual Studio.  It holds true to its claim to be a "code snippet IDE."  In fact, you don't even have to use it for LINQ!  Say you just want to run a method and see what kind of data comes out:  rather than creating a temporary unit-test in your Visual Studio directory, you can simply write the C# code snippet in LINQPad and run it!&lt;br /&gt;&lt;br /&gt;If you're new to LINQ, LINQPad actually comes with a hearty set of code samples to help you get started.&lt;br /&gt;&lt;br /&gt;Oh, yeah, and you can also use it to run SQL queries and commands if you want.&lt;br /&gt;&lt;br /&gt;Overall, I've been extremely impressed by all that I can do with LINQPad.  Now I'm trying to get my bosses to invest in an Autocomplete license for it, and looking forward to the increased productivity I can expect from that feature.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8924020273529189874-40714889101588553?l=dotnetdom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dotnetdom.blogspot.com/feeds/40714889101588553/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dotnetdom.blogspot.com/2009/02/linqpad-my-new-favorite-tool.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8924020273529189874/posts/default/40714889101588553'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8924020273529189874/posts/default/40714889101588553'/><link rel='alternate' type='text/html' href='http://dotnetdom.blogspot.com/2009/02/linqpad-my-new-favorite-tool.html' title='LinqPad, my new favorite tool'/><author><name>J²</name><uri>http://www.blogger.com/profile/14478332251437579476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://photos1.blogger.com/img/268/3041/1024/IMGP17751.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8924020273529189874.post-3930614945142173286</id><published>2009-02-19T11:49:00.000-08:00</published><updated>2009-02-19T12:56:03.276-08:00</updated><title type='text'>Joining entities using the "new" operator</title><content type='html'>I took some time in my last post to explain that two database queries are better than many database queries.  Namely, it's better to do one database query and create a mapping with the returned data, than it is to perform a new database query for every chunk of information that we want.  (I should note that this is obviously only true if the results of your two database queries can be limited to a size that roughly fits the amount of data you'd otherwise be requesting.  If you're clever, this can usually be the case.)&lt;br /&gt;&lt;br /&gt;As I played around a bit more with Linq, I found another syntax that can be used to join objects together.  For example, the following Linq (to SQL) code:&lt;br /&gt;    &lt;div id="Panel1" class="OuterPanel"&gt;&lt;div id="OuterPanel" class="CodeViewPanel"&gt;&lt;table id="CodeTable" border="0"&gt;   &lt;tbody&gt;&lt;tr id="Row1"&gt;&lt;br /&gt; &lt;td id="Lines" class="Lines"&gt;&lt;pre&gt;1&lt;br /&gt;2&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td id="SourceCode" class="Code"&gt;&lt;span id="CodeText"&gt;&lt;pre&gt;from ec &lt;span style="color: rgb(0, 0, 255);"&gt;in&lt;/span&gt; EntityCategory&lt;br /&gt;select &lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; {ec, te = from te &lt;span style="color: rgb(0, 0, 255);"&gt;in&lt;/span&gt; ec.TrackedEntity select te}&lt;/pre&gt;&lt;/span&gt;&lt;/td&gt;  &lt;/tr&gt;  &lt;/tbody&gt;&lt;/table&gt;... will produce objects of a new Anonymous type with the following elements:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;EntityCategory ec&lt;/li&gt;&lt;li&gt;IEnumerable&lt;trackedentity&gt; te&lt;/trackedentity&gt;&lt;/li&gt;&lt;/ul&gt;This approach can use a single SQL round-trip, which you'd think would be ideal.  After all, if two is better than many, shouldn't one be better than two?  But there are a few things to keep in mind:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Because it creates an Anonymous data type, the returned results don't really lend themselves to being passed around your program as arguments.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;There is actually quite a bit of overhead associated with this method.  The generated SQL query is a lot more expensive for the database, and the returned data set has a lot of unnecessarily-duplicated data.  Once the data returns from the database, it has to be parsed and organized by the framework (Entity or Linq to SQL) in much the same way as the JoinedEntityMap class that I mentioned in my last post.  So this syntax can run much more slowly, despite reducing the number of database round-trips.&lt;/li&gt;&lt;/ol&gt;That said, this syntax can be useful in certain circumstances, so it's good to keep this alternative in the back of your mind.&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8924020273529189874-3930614945142173286?l=dotnetdom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dotnetdom.blogspot.com/feeds/3930614945142173286/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dotnetdom.blogspot.com/2009/02/joining-entities-using-new-operator.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8924020273529189874/posts/default/3930614945142173286'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8924020273529189874/posts/default/3930614945142173286'/><link rel='alternate' type='text/html' href='http://dotnetdom.blogspot.com/2009/02/joining-entities-using-new-operator.html' title='Joining entities using the &quot;new&quot; operator'/><author><name>J²</name><uri>http://www.blogger.com/profile/14478332251437579476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://photos1.blogger.com/img/268/3041/1024/IMGP17751.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8924020273529189874.post-6808117890270070764</id><published>2009-02-17T14:39:00.000-08:00</published><updated>2009-02-17T17:12:55.174-08:00</updated><title type='text'>Joining entities to avoid database roundtrips</title><content type='html'>In my last post, I hinted that I had an alternative in mind for the Eager Loading problem that has vexed me over the past few days.&lt;br /&gt;&lt;br /&gt;First of all, it's important to understand what we intend to gain by eager loading--fewer database round-trips.  You see, every time your program asks the database for information, there is considerable overhead with establishing the connection, waiting for your request to go over the wire, and waiting for the response to come back.  If your queries return large data sets, this overhead will have a minimal impact.  But if you're doing a whole bunch of tiny queries, this overhead can make a huge difference.  In my case, where I often work from home and connect to the database at work, the overhead from these so-called "round-trips" can actually take more time than everything else in a typical page load.&lt;br /&gt;&lt;br /&gt;So rather than saying:&lt;br /&gt;&lt;div id="Panel1" class="OuterPanel"&gt;&lt;div id="OuterPanel" class="CodeViewPanel"&gt;&lt;table id="CodeTable" border="0"&gt;   &lt;tbody&gt;&lt;tr id="Row1"&gt;&lt;br /&gt;    &lt;td id="Lines" class="Lines"&gt;&lt;pre&gt;1&lt;br /&gt;2&lt;br /&gt;3&lt;br /&gt;4&lt;br /&gt;5&lt;br /&gt;6&lt;br /&gt;7&lt;br /&gt;8&lt;br /&gt;9&lt;br /&gt;10&lt;br /&gt;11&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td id="SourceCode" class="Code"&gt;&lt;span id="CodeText"&gt;&lt;pre&gt;TrackedEntityBO tebo = &lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; TrackedEntityBO(context);&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;foreach&lt;/span&gt; (RepeaterItem item &lt;span style="color: rgb(0, 0, 255);"&gt;in&lt;/span&gt; Repeater1.Items)&lt;br /&gt;{&lt;br /&gt;CheckBoxList list = (CheckBoxList)item.FindControl("&lt;span style="color: rgb(139, 0, 0);"&gt;CheckBoxList1&lt;/span&gt;");&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;foreach&lt;/span&gt; (ListItem li &lt;span style="color: rgb(0, 0, 255);"&gt;in&lt;/span&gt; list.Items)&lt;br /&gt;{&lt;br /&gt;  TrackedEntity te = tebo.getById(Decimal.Parse(li.Value)); &lt;span style="color: rgb(0, 128, 0);"&gt;// Run 1 query per TrackedEntity&lt;/span&gt;&lt;br /&gt;  ...&lt;br /&gt;}&lt;br /&gt;}&lt;/pre&gt;&lt;/span&gt;&lt;/td&gt;   &lt;/tr&gt;  &lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;/div&gt;... , I could save a lot of time by saying:&lt;div id="Panel1" class="OuterPanel"&gt;&lt;div id="OuterPanel" class="CodeViewPanel"&gt;        &lt;table id="CodeTable" border="0"&gt;   &lt;tbody&gt;&lt;tr id="Row1"&gt;&lt;br /&gt;    &lt;td id="Lines" class="Lines"&gt;&lt;pre&gt;1&lt;br /&gt;2&lt;br /&gt;3&lt;br /&gt;4&lt;br /&gt;5&lt;br /&gt;6&lt;br /&gt;7&lt;br /&gt;8&lt;br /&gt;9&lt;br /&gt;10&lt;br /&gt;11&lt;br /&gt;12&lt;br /&gt;13&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td id="SourceCode" class="Code"&gt;&lt;span id="CodeText"&gt;&lt;pre&gt;TrackedEntityBO tebo = &lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; TrackedEntityBO(context);&lt;br /&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;// Runs a single linq query for all TrackedEntities&lt;/span&gt;&lt;br /&gt;Dictionary&amp;lt;&lt;span style="color: rgb(0, 0, 255);"&gt;decimal&lt;/span&gt;, TrackedEntity&amp;gt; ueMap = tebo.getAll().ToDictionary(c =&amp;gt; c.TrackedEntityId);&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;foreach&lt;/span&gt; (RepeaterItem item &lt;span style="color: rgb(0, 0, 255);"&gt;in&lt;/span&gt; Repeater1.Items)&lt;br /&gt;{&lt;br /&gt;CheckBoxList list = (CheckBoxList)item.FindControl("&lt;span style="color: rgb(139, 0, 0);"&gt;CheckBoxList1&lt;/span&gt;");&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;foreach&lt;/span&gt; (ListItem li &lt;span style="color: rgb(0, 0, 255);"&gt;in&lt;/span&gt; list.Items)&lt;br /&gt;{&lt;br /&gt;   TrackedEntity te = ueMap[Decimal.Parse(li.Value)];&lt;br /&gt;   ...&lt;br /&gt;}&lt;br /&gt;}&lt;/pre&gt;&lt;/span&gt;&lt;/td&gt;   &lt;/tr&gt;  &lt;/tbody&gt;&lt;/table&gt;The folks who designed the Entity Framework were aware of this, and they took action to prevent round-trips as much as possible.  For example:&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;ol&gt;&lt;li&gt;Each context instance can cache a lot of the data that it gathers.  If a later LINQ query on the same context can be determined to contain only data that has previously been cached, the Framework will use the cached data rather than executing another query.&lt;/li&gt;&lt;li&gt;Unlike Linq to SQL, the Entity Framework will not make a database query without being asked.  For example, the following code will produce an exception because the EntityCategory object never got loaded into the context:&lt;br /&gt;&lt;div id="Panel1" class="OuterPanel"&gt;&lt;div id="OuterPanel" class="CodeViewPanel"&gt;        &lt;table id="CodeTable" border="0"&gt;&lt;br /&gt;   &lt;tbody&gt;&lt;tr id="Row1"&gt;&lt;br /&gt;    &lt;td id="Lines" class="Lines"&gt;&lt;pre&gt;1&lt;br /&gt;2&lt;br /&gt;3&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td id="SourceCode" class="Code"&gt;&lt;span id="CodeText"&gt;&lt;pre&gt;TrackedEntity e = (from te &lt;span style="color: rgb(0, 0, 255);"&gt;in&lt;/span&gt; context.TrackedEntity&lt;br /&gt;         select te).First();&lt;br /&gt;Console.WriteLine (e.EntityCategory.Name);&lt;/pre&gt;&lt;/span&gt;&lt;/td&gt;   &lt;/tr&gt;  &lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;/div&gt;&lt;/li&gt;&lt;/ol&gt; As I pointed out in my last post, you simply can't make assumptions regarding which items have been loaded into the context.  That means if you want to get certain objects associated with other objects, you'll either have to do a whole bunch of queries, or put both groups of objects into a data structure that maps them to one another.  Thanks to the power of the .NET framework, however, this isn't all that difficult.  For example, with relatively few lines of actual code, I was able to make the following statements possible:&lt;br /&gt;     &lt;div id="Panel1" class="OuterPanel"&gt;&lt;div id="OuterPanel" class="CodeViewPanel"&gt;&lt;table id="CodeTable" border="0"&gt;   &lt;tbody&gt;&lt;tr id="Row1"&gt;&lt;br /&gt;    &lt;td id="Lines" class="Lines"&gt;&lt;pre&gt;1&lt;br /&gt;2&lt;br /&gt;3&lt;br /&gt;4&lt;br /&gt;5&lt;br /&gt;6&lt;br /&gt;7&lt;br /&gt;8&lt;br /&gt;9&lt;br /&gt;10&lt;br /&gt;11&lt;br /&gt;12&lt;br /&gt;13&lt;br /&gt;14&lt;br /&gt;15&lt;br /&gt;16&lt;br /&gt;17&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td id="SourceCode" class="Code"&gt;&lt;span id="CodeText"&gt;&lt;pre&gt;IQueryable&amp;lt;TrackedEntity&amp;gt; teQuery = from te &lt;span style="color: rgb(0, 0, 255);"&gt;in&lt;/span&gt; context.TrackedEntity&lt;br /&gt;                                 orderby te.Name&lt;br /&gt;                                 select te;&lt;br /&gt;IQueryable&amp;lt;EntityCategory&amp;gt; ecQuery = from te &lt;span style="color: rgb(0, 0, 255);"&gt;in&lt;/span&gt; teQuery&lt;br /&gt;                                  let ec = te.EntityCategory&lt;br /&gt;                                  orderby ec.Name&lt;br /&gt;                                  select ec;&lt;br /&gt;JoinedEntityMap&amp;lt;EntityCategory, TrackedEntity&amp;gt; j =&lt;br /&gt; ecQuery.ToMap(c =&amp;gt; c.EntityCategoryId, teQuery, te =&amp;gt; te.EntityCategory);&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;foreach&lt;/span&gt; (EntityCategory c &lt;span style="color: rgb(0, 0, 255);"&gt;in&lt;/span&gt; j.UniqueKeys)&lt;br /&gt;{&lt;br /&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;foreach&lt;/span&gt; (TrackedEntity e &lt;span style="color: rgb(0, 0, 255);"&gt;in&lt;/span&gt; j[c])&lt;br /&gt; {&lt;br /&gt;     Console.WriteLine(c.Name + "&lt;span style="color: rgb(139, 0, 0);"&gt;: &lt;/span&gt;" + e.Name);&lt;br /&gt; }&lt;br /&gt;}&lt;/pre&gt;&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;With negligible memory overhead, the above code causes a grand total of two SQL queries and takes 110 milliseconds to run with 4 EntityCategories and 47 TrackedEntities, as opposed to the code below, which takes 251 milliseconds:&lt;/div&gt;&lt;/div&gt;&lt;div id="Panel1" class="OuterPanel"&gt;&lt;div id="OuterPanel" class="CodeViewPanel"&gt;&lt;table id="CodeTable" border="0"&gt;   &lt;tbody&gt;&lt;tr id="Row1"&gt;&lt;br /&gt;    &lt;td id="Lines" class="Lines"&gt;&lt;pre&gt;1&lt;br /&gt;2&lt;br /&gt;3&lt;br /&gt;4&lt;br /&gt;5&lt;br /&gt;6&lt;br /&gt;7&lt;br /&gt;8&lt;br /&gt;9&lt;br /&gt;10&lt;br /&gt;11&lt;br /&gt;12&lt;br /&gt;13&lt;br /&gt;14&lt;br /&gt;15&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td id="SourceCode" class="Code"&gt;&lt;span id="CodeText"&gt;&lt;pre&gt;IQueryable&amp;lt;EntityCategory&amp;gt; ecQuery = from ec &lt;span style="color: rgb(0, 0, 255);"&gt;in&lt;/span&gt; context.EntityCategory&lt;br /&gt;                                    orderby ec.Name&lt;br /&gt;                                    select ec;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;foreach&lt;/span&gt; (EntityCategory c &lt;span style="color: rgb(0, 0, 255);"&gt;in&lt;/span&gt; ecQuery)&lt;br /&gt;{&lt;br /&gt;   IQueryable&amp;lt;TrackedEntity&amp;gt; teQuery = from te &lt;span style="color: rgb(0, 0, 255);"&gt;in&lt;/span&gt; context.TrackedEntity&lt;br /&gt;                                       where te.EntityCategory.EntityCategoryId == c.EntityCategoryId&lt;br /&gt;                                       orderby te.Name&lt;br /&gt;                                       select te;&lt;br /&gt;   &lt;span style="color: rgb(0, 0, 255);"&gt;foreach&lt;/span&gt; (TrackedEntity e &lt;span style="color: rgb(0, 0, 255);"&gt;in&lt;/span&gt; teQuery)&lt;br /&gt;   {&lt;br /&gt;       Console.WriteLine(c.Name + "&lt;span style="color: rgb(139, 0, 0);"&gt;: &lt;/span&gt;" + e.Name);&lt;br /&gt;   }&lt;br /&gt;}&lt;/pre&gt;&lt;/span&gt;&lt;/td&gt;   &lt;/tr&gt;  &lt;/tbody&gt;&lt;/table&gt;With that kind of difference on such a small scale, you can imagine how much of a difference it could make if you had hundreds, or even thousands of records in each table!&lt;br /&gt;&lt;br /&gt;Another potential benefit to this approach is that the main page's code can create the data it knows will be needed, and then hand strongly-typed data to each user control in turn.  It not only makes it possible for the user controls to be more specific in what sort of data they need as parameters, but it also increases the transparency of your data accesses.  With most of your calls to the data layer occurring in one code file, it becomes obvious what's taking so much time to load.  And if you're not using an HttpContext-based Entity context (which we are), it can also simplify the problems you'll run into with conflicting contexts.&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8924020273529189874-6808117890270070764?l=dotnetdom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dotnetdom.blogspot.com/feeds/6808117890270070764/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dotnetdom.blogspot.com/2009/02/joining-entities-to-avoid-database.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8924020273529189874/posts/default/6808117890270070764'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8924020273529189874/posts/default/6808117890270070764'/><link rel='alternate' type='text/html' href='http://dotnetdom.blogspot.com/2009/02/joining-entities-to-avoid-database.html' title='Joining entities to avoid database roundtrips'/><author><name>J²</name><uri>http://www.blogger.com/profile/14478332251437579476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://photos1.blogger.com/img/268/3041/1024/IMGP17751.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8924020273529189874.post-7838883420457074616</id><published>2009-02-16T15:08:00.000-08:00</published><updated>2009-02-16T16:09:54.980-08:00</updated><title type='text'>A better understanding of Eager Loading</title><content type='html'>It turns out to be a very bad idea to rely on the behavior that I mentioned in my last posting.  Even though the first Linq query I mentioned &lt;span style="font-style: italic;"&gt;tends&lt;/span&gt; to cause those requested objects to be loaded into the context, there is no guarantee that those are the &lt;span style="font-style: italic;"&gt;only&lt;/span&gt; objects that will be brought in.  For example, if I run the following code:&lt;div style="overflow: auto;"&gt;&lt;pre style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&lt;/span&gt;&lt;br /&gt;   List&amp;lt;EntityCategory&amp;gt; l2 = (from ec &lt;span style="color: rgb(0, 0, 255);"&gt;in&lt;/span&gt; context.EntityCategory.Include(c =&amp;gt; c.TrackedEntity)&lt;br /&gt;                                    select ec).ToList();&lt;br /&gt;&lt;br /&gt;   List&amp;lt;EntityCategory&amp;gt; l1 = (from ec &lt;span style="color: rgb(0, 0, 255);"&gt;in&lt;/span&gt; context.EntityCategory&lt;br /&gt;                                    from te &lt;span style="color: rgb(0, 0, 255);"&gt;in&lt;/span&gt; ec.TrackedEntity&lt;br /&gt;                                    from ue &lt;span style="color: rgb(0, 0, 255);"&gt;in&lt;/span&gt; te.User&lt;br /&gt;                                    where ue.UserId == user.UserId&lt;br /&gt;                                    orderby ec.Name&lt;br /&gt;                                    select ec).DistinctBy(c =&amp;gt; c.EntityCategoryId).ToList();&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;... l1.First().TrackedEntity will contain ALL of the tracked entities related to the given entity category.  This is because the first statement loaded all of these entities into the context, and the second statement reused the objects that were created there.&lt;br /&gt;&lt;br /&gt;So, what have we learned?  We can only trust a LINQ statement to give us the data we ask for&lt;span style="font-weight: bold;"&gt; in the select statement&lt;/span&gt;, and we should never trust associated entity objects to even exist, much less contain what we're expecting.&lt;br /&gt;&lt;br /&gt;I have a plan for dealing with this, which I'll detail once I get the kinks worked out.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8924020273529189874-7838883420457074616?l=dotnetdom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dotnetdom.blogspot.com/feeds/7838883420457074616/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dotnetdom.blogspot.com/2009/02/better-understanding-of-eager-loading.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8924020273529189874/posts/default/7838883420457074616'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8924020273529189874/posts/default/7838883420457074616'/><link rel='alternate' type='text/html' href='http://dotnetdom.blogspot.com/2009/02/better-understanding-of-eager-loading.html' title='A better understanding of Eager Loading'/><author><name>J²</name><uri>http://www.blogger.com/profile/14478332251437579476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://photos1.blogger.com/img/268/3041/1024/IMGP17751.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8924020273529189874.post-7194860976726104278</id><published>2009-02-13T15:08:00.000-08:00</published><updated>2009-02-13T16:13:33.926-08:00</updated><title type='text'>Eager loading limitations (driving me crazy!)</title><content type='html'>Yesterday I talked about some strategies for Eager Loading in the Entity Framework.  Well, I'm running into a really perplexing situation now.&lt;br /&gt;&lt;br /&gt;If I run a LINQ query like this:&lt;br /&gt;&lt;blockquote style="font-family: courier new;"&gt;List&lt;entitycategory&gt; l1 =&lt;br /&gt;    from u in context.UserSet&lt;br /&gt;    where u.UserId == user.UserId&lt;br /&gt;    from t in u.UserEntities&lt;br /&gt;    orderby t.EntityCategory.Name&lt;br /&gt;    select t.EntityCategory&lt;/blockquote&gt;I find that all of the entities accessed by the query are eager loaded... sort of.  I can access l1.First().TrackedEntity.First().Name, for example.  But l1.First().TrackedEntity.IsLoaded is false!  So the data exists in the context, but the context doesn't think it's loaded.  Furthermore, adding an Include("TrackedEntity") doesn't do &lt;span style="font-style: italic;"&gt;a thing&lt;/span&gt; when you do joins.  So even though all the information gets pulled into memory correctly, if I put any "if(!isloaded) load" code in my front-end (which would normally be a robust way of doing things), it will &lt;span style="font-style: italic;"&gt;reload&lt;/span&gt; all the same data from the database for each EntityCategory.&lt;br /&gt;&lt;br /&gt;Now, I could do a fancy query like this:&lt;br /&gt;&lt;blockquote style="font-family: courier new;"&gt;from ec in context.EntityCategory.Include("TrackedEntity")&lt;br /&gt;where ec.TrackedEntity.Any(te =&gt; te.User.Any(u =&gt; u.UserId == user.UserId))&lt;br /&gt;select ec&lt;/blockquote&gt;But the eager-loaded results would give me ALL of the tracked entities for each entity category, and not just the ones selected by the given user.&lt;br /&gt;&lt;br /&gt;Is there any way make a statement that selectively joins tables AND eager-loads ONLY the entities included in the join, marking the appropriate EntityCollection as Loaded?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8924020273529189874-7194860976726104278?l=dotnetdom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dotnetdom.blogspot.com/feeds/7194860976726104278/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dotnetdom.blogspot.com/2009/02/eager-loading-limitations-driving-me.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8924020273529189874/posts/default/7194860976726104278'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8924020273529189874/posts/default/7194860976726104278'/><link rel='alternate' type='text/html' href='http://dotnetdom.blogspot.com/2009/02/eager-loading-limitations-driving-me.html' title='Eager loading limitations (driving me crazy!)'/><author><name>J²</name><uri>http://www.blogger.com/profile/14478332251437579476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://photos1.blogger.com/img/268/3041/1024/IMGP17751.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8924020273529189874.post-1775083838711976680</id><published>2009-02-12T11:05:00.000-08:00</published><updated>2009-02-12T14:13:47.379-08:00</updated><title type='text'>Lazy and Eager Loading Strategies in the Entity Framework</title><content type='html'>We're working on a Timesheets project to help us learn .NET. Our architecture uses the fairly new .NET Entity Framework for its data model. We use three layers:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;The data access layer consists of an EDMX file, which defines CLR objects based on our database schema. (e.g. &lt;span style="font-family:courier new;"&gt;TrackedTime&lt;/span&gt;)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The business layer consists of "business objects" with methods that do things with the objects in the data access layer. (e.g. &lt;span style="font-family:courier new;"&gt;public List&lt;trackedtime&gt; getByUserAndDate(User user, DateTime dateTime)&lt;/trackedtime&gt;&lt;/span&gt;)&lt;/li&gt;&lt;li&gt;The front-end is an ASP.NET Website.&lt;/li&gt;&lt;/ol&gt;So, to get a list of all of a user's tracked times for a particular day, our front-end can call the following method:&lt;br /&gt;&lt;pre&gt;public List&lt;trackedtime&gt; getByUserAndDate(User user, DateTime dateTime, params string[] includes)&lt;br /&gt;{&lt;br /&gt;  ObjectQuery&lt;trackedtime&gt; queryObject = context.TrackedTime;&lt;br /&gt;  return queryByUserAndDate(queryObject, user, dateTime).ToList();&lt;br /&gt;}&lt;/trackedtime&gt;&lt;/trackedtime&gt;&lt;/pre&gt;The method "queryByUserAndDate" generates a LINQ query that asks for all TrackedTime objects in the given ObjectQuery that have the given User and Date. The list returned by "getByUserAndDate" can then be bound to a control in the front-end, such as a DataGrid, using an ObjectDataSource.&lt;br /&gt;&lt;br /&gt;This works fine, as long as our DataGrid only displays the data tied directly to the TrackedTime object. If we want to have a field in the DataGrid that shows all the TrackedEntities that are related to our TrackedTime object, we will need to make sure they get loaded from the database. There are two ways to do this.&lt;br /&gt;&lt;br /&gt;One way is Lazy Loading: for each row in our datagrid, we have to insert the following code before the TrackedEntities get accessed:&lt;br /&gt;&lt;pre&gt;if (!trackedTime.TrackedEntities.IsLoaded)&lt;br /&gt;{&lt;br /&gt;  trackedTime.TrackedEntities.Load();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;There are a few problems with this approach:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;It messes up our three-tiered architecture, since data is being loaded almost directly from the front-end layer.&lt;/li&gt;&lt;li&gt;If the context object used in getByUserAndDate has been disposed before this code gets reached, it will throw an exception. This isn't such a problem in our architecture, for reasons I will probably discuss in another blog posting, but for many applications it simply wouldn't work.&lt;/li&gt;&lt;li&gt;getByUserAndDate only made one database query to load in all "N" TrackedTime objects. Now, we're manually forcing "N" database queries to load in the TrackedEntity objects. With all the overhead involved in a database query, this can slow the overall process significantly.&lt;/li&gt;&lt;/ol&gt;The other approach is to use so-called "Eager" loading. In this approach, we make a method getByUserAndDateWithTrackedEntities to load the TrackedEntities in the initial LINQ statement:&lt;br /&gt;&lt;pre&gt;public List&lt;trackedtime&gt; getByUserAndDateWithTrackedEntities(User user, DateTime dateTime)&lt;br /&gt;{&lt;br /&gt;  ObjectQuery&lt;trackedtime&gt; queryObject = context.TrackedTime&lt;span style="font-weight: bold;"&gt;.Include("TrackedEntities")&lt;/span&gt;;&lt;br /&gt;  return queryByUserAndDate(queryObject, user, dateTime).ToList();&lt;br /&gt;}&lt;br /&gt;&lt;/trackedtime&gt;&lt;/trackedtime&gt;&lt;/pre&gt;This has the advantage of using a single database call to load all TrackedEntities for all the TrackedTime objects that are going to be returned. However, it creates a couple of new problems:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Experienced programmers are loath to use Strings to define data that's tied to the object model. If, for example, you mistakenly say "TrackedEntity" instead, you'll have no idea that there's something wrong with your code until it runs. If this method only gets run in a corner case, you might not catch the bug for a long, long time. Studies show that it takes enormously more time to fix a bug when it gets caught later in the production cycle. We want the compiler to tell us if we're making a dumb mistake as soon as we make it. It's even better if we can use Intellisense to help us avoid making the error in the first place!&lt;/li&gt;&lt;li&gt;If we have to create a new method for every possible combination of includes, this could get really cumbersome. Are we going to make a getByDateWithUserAndTrackedEntitiesAndTheirCategories method, too? Ideally, we would like to have one method that could take the includes as arguments.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;To solve problem #1, a gentleman named Matthieu MEZIL (est-il Français?) &lt;a href="http://msmvps.com/blogs/matthieu/archive/2008/06/06/entity-framework-include-with-func-next.aspx"&gt;created Extension Methods&lt;/a&gt; that basically snap into the ObjectQuery class to give you new ways of calling the Include method. After creating a class based on the one he created, we can change getByUserAndDateWithTrackedEntities thusly:&lt;br /&gt;&lt;pre&gt;ObjectQuery&lt;trackedtime&gt; queryObject = context.TrackedTime.Include(&lt;span style="font-weight: bold;"&gt;c =&gt; c.TrackedEntities&lt;/span&gt;);&lt;/trackedtime&gt;&lt;/pre&gt;This gives us slightly more overhead because it basically just uses reflection behind the scenes to create the "TrackedEntities" string at run-time. But it's a trifle compared to all the other overhead inherent in ASP.NET, and it is now fully strongly typed.&lt;br /&gt;&lt;br /&gt;Is there a way to solve problem #2 in this context as well? To be honest, M. MEZIL's extension methods use deep magic that is beyond my current understanding of the .NET framework, so I haven't figured out how one might go about altering the getByUserAndDate method to allow the same kind of "lambda expression" to be passed into it, although there is certainly a way to do so. But the limitations of the front-end leave us with certain practical concerns as well, which might make it impossible (or at least really annoying) to call the method this way. You see, ASP.NET relies heavily on reflection to make it easier to get the "it just works" behavior that Microsoft is striving for. For example, there appears to be no way in my .aspx code to tell the ObjectDataSource to use actual objects as arguments to my business layer. If I had a method that looked like this:&lt;br /&gt;&lt;pre&gt;public List&lt;trackedtime&gt; getByUserAndDateWithTrackedEntities(String userId, String dateTimeStr)&lt;/trackedtime&gt;&lt;/pre&gt;... I could just use the wizard in Visual Web Developer to create simple XML-ish code that tells the framework where to get the userId and dateTime to use when calling the getByUserAndDateWithTrackedEntities method. But if I want to pass actual objects around (which not only helps us prevent the situation mentioned in #1, but also saves us from re-loading the same User object from the entity framework for every control on the page that wants information from it), I have to leave the parameter values blank in the .aspx file and put something like this in my code-behind:&lt;br /&gt;&lt;pre&gt;protected void TodayTimes_Selecting(object sender, ObjectDataSourceSelectingEventArgs e)&lt;br /&gt;{&lt;br /&gt;  e.InputParameters["user"] = currentUser;&lt;br /&gt;  e.InputParameters["dateTime"] = DateTime.Parse(DateList.SelectedValue);&lt;br /&gt;}&lt;/pre&gt;It's ugly, but that's the price we pay for those nifty wizards and that nice design view. If I want to bind the GridView programmatically I can, but I would have to sacrifice some of what makes ASP.NET attractive in the first place. Let's assume for a moment that I won't always want to make that sacrifice. How would I add a lambda expression to the InputParameters in the above code? If it's possible, it's undoubtedly messy, and since the function is only getting invoked through reflection anyway, we've already lost the benefits of Intellisense and compiler checks, so why bother?&lt;br /&gt;&lt;br /&gt;With that in mind, let's examine a way to solve problem #2 &lt;span style="font-style: italic;"&gt;without &lt;/span&gt;solving problem #1.  I begin by creating the following method extension:&lt;br /&gt;&lt;pre&gt;public static ObjectQuery&lt;t&gt; Include&lt;t&gt;(this ObjectQuery&lt;t&gt; mainQuery, params string[] paths)&lt;br /&gt;{&lt;br /&gt;  ObjectQuery&lt;t&gt; q = mainQuery;&lt;br /&gt;  foreach (string path in paths)&lt;br /&gt;  {&lt;br /&gt;      q = q.Include(path);&lt;br /&gt;  }&lt;br /&gt;  return q;&lt;br /&gt;}&lt;/t&gt;&lt;/t&gt;&lt;/t&gt;&lt;/t&gt;&lt;/pre&gt;As you can see, all this does is call Include iteratively on every string that gets passed in to it. Now we can change our getByUserAndDate function like so:&lt;br /&gt;&lt;pre&gt;public List&lt;trackedtime&gt; getByUserAndDate(User user, DateTime dateTime&lt;span style="font-weight: bold;"&gt;, params string[] includes&lt;/span&gt;)&lt;br /&gt;{&lt;br /&gt;  ObjectQuery&lt;trackedtime&gt; queryObject = context.TrackedTime&lt;span style="font-weight: bold;"&gt;.Include(includes)&lt;/span&gt;;&lt;br /&gt;  return queryByUserAndDate(queryObject, user, dateTime).ToList();&lt;br /&gt;}&lt;/trackedtime&gt;&lt;/trackedtime&gt;&lt;/pre&gt;Then, depending on how much data we want to load eagerly, we can call this programmatically like so:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;myGridView.DataSource = trackedTimeBo.getByUserAndDate(user, dateTime);&lt;/li&gt;&lt;li&gt;myGridView.DataSource = trackedTimeBo.getByUserAndDate(user, dateTime, "TrackedEntities");&lt;/li&gt;&lt;li&gt;myGridView.DataSource = trackedTimeBo.getByUserAndDate(user, dateTime, "TrackedEntities", "TrackedEntities.EntityCategory");&lt;/li&gt;&lt;li&gt;...&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;Or, in the case mentioned earlier, we can add the input parameter like so:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;e.InputParameters["includes"] = new string[] {};&lt;/li&gt;&lt;li&gt;e.InputParameters["includes"] = new string[] {"TrackedEntities"};&lt;/li&gt;&lt;li&gt;e.InputParameters["includes"] = new string[] {"TrackedEntities", "TrackedEntities.EntityCategory"};&lt;/li&gt;&lt;li&gt;...&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;So we end up with a couple of good ways to do Eager Loading in the Entity Framework, each with their advantages and disadvantages. We'll probably end up using a combination of the two. Or maybe we'll find another way that makes even more sense. Who knows?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8924020273529189874-1775083838711976680?l=dotnetdom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dotnetdom.blogspot.com/feeds/1775083838711976680/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dotnetdom.blogspot.com/2009/02/lazy-and-eager-loading-strategies-in.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8924020273529189874/posts/default/1775083838711976680'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8924020273529189874/posts/default/1775083838711976680'/><link rel='alternate' type='text/html' href='http://dotnetdom.blogspot.com/2009/02/lazy-and-eager-loading-strategies-in.html' title='Lazy and Eager Loading Strategies in the Entity Framework'/><author><name>J²</name><uri>http://www.blogger.com/profile/14478332251437579476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://photos1.blogger.com/img/268/3041/1024/IMGP17751.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8924020273529189874.post-6984884090768045532</id><published>2009-02-10T11:04:00.001-08:00</published><updated>2009-02-10T11:21:12.739-08:00</updated><title type='text'>Watch the ViewState While Debugging</title><content type='html'>In my previous post, I briefly showed how to use the ViewState to persist data.  This post will overcome the difficulty we have in seeing what data is currently in the ViewState while debugging.  The problem?  ViewState is a &lt;a href="http://msdn.microsoft.com/en-us/library/system.web.ui.statebag.aspx"&gt;StateBag&lt;/a&gt;, which, unlike Hashtable, does not have a default visualizer that makes its values easy for the debugger to look at.  In fact, the actual keys and values don't appear to be contained within the StateBag object itself, which makes drilling through its data pointless.  (I'm guessing that since the ViewState has per-user-control-per-instance values, it probably stores the real data in the ASP.NET "magic zone" where all the context loading and such takes place.  The StateBag probably just provides access methods to wherever the data is really stored.)&lt;br /&gt;&lt;br /&gt;So how can you get a quick-and-easy view of the current ViewState?  Just add the following line to your Watch panel:&lt;br /&gt;&lt;blockquote&gt;new System.Collections.Hashtable(ViewState)&lt;/blockquote&gt;The Hashtable constructor iterates through all of the key/value pairs of the StateBag and creates a Hashtable object out of it.  Since Hashtable has a key/value pair visualizer in Visual Studio, you get a nice, clean table of keys and values.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8924020273529189874-6984884090768045532?l=dotnetdom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dotnetdom.blogspot.com/feeds/6984884090768045532/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dotnetdom.blogspot.com/2009/02/watch-viewstate-while-debugging.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8924020273529189874/posts/default/6984884090768045532'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8924020273529189874/posts/default/6984884090768045532'/><link rel='alternate' type='text/html' href='http://dotnetdom.blogspot.com/2009/02/watch-viewstate-while-debugging.html' title='Watch the ViewState While Debugging'/><author><name>J²</name><uri>http://www.blogger.com/profile/14478332251437579476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://photos1.blogger.com/img/268/3041/1024/IMGP17751.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8924020273529189874.post-1274148693484941567</id><published>2009-02-10T10:36:00.000-08:00</published><updated>2009-02-10T11:04:12.100-08:00</updated><title type='text'>Persisting Data in User Controls with ViewState</title><content type='html'>In ASP.NET, the ViewState is used to persist data across requests.  Let's say, for example, I want to use a User Control that will show information based on a particular date.  I could create a property in that control that looks like this:&lt;br /&gt;&lt;blockquote&gt;    private DateTime _Date;&lt;br /&gt;    public DateTime Date&lt;br /&gt;    {&lt;br /&gt;        set&lt;br /&gt;        {&lt;br /&gt;            _Date = value;&lt;br /&gt;            ViewState["Date"] = value;&lt;br /&gt;        }&lt;br /&gt;        get&lt;br /&gt;        {&lt;br /&gt;            if (_Date.Ticks == 0 &amp;amp;&amp;amp; ViewState["Date"] != null)&lt;br /&gt;            {&lt;br /&gt;                _Date = (DateTime)ViewState["Date"];&lt;br /&gt;            }&lt;br /&gt;            return _Date;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;/blockquote&gt;... which would make it possible for me to "set and forget" the date from the page containing that user control.  For example:&lt;br /&gt;&lt;blockquote&gt;    protected void Page_Load(object sender, EventArgs e)&lt;br /&gt;    {&lt;br /&gt;        if (!Page.IsPostBack)&lt;br /&gt;        {&lt;br /&gt;            AddTrackedTime1.Date = DateTime.Today;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;/blockquote&gt;So the first time the page loads, it sets the user control's date.  You could have events set up to change the date on that user control if you want.  Each time the date gets set, it will add a binary value to the ViewState, which will persist in the form of a hidden field on the webpage that is being viewed.  When the time comes to do something with that date value, it will automatically be loaded out of the ViewState.  Because the viewstate is persisted in a hidden form field, it will continue to work properly even if the user clicks "back" several times in the browser and then clicks on a control from their browsing history.  Also, unlike the Session, the ViewState is specific to the control instance, so you could have several of these controls on the same page and they wouldn't step on each others' toes.&lt;br /&gt;&lt;br /&gt;The only potential downside is that you increase the amount of data sent to and from the browser, which could slow transactions somewhat.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8924020273529189874-1274148693484941567?l=dotnetdom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dotnetdom.blogspot.com/feeds/1274148693484941567/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dotnetdom.blogspot.com/2009/02/persisting-data-in-user-controls-with.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8924020273529189874/posts/default/1274148693484941567'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8924020273529189874/posts/default/1274148693484941567'/><link rel='alternate' type='text/html' href='http://dotnetdom.blogspot.com/2009/02/persisting-data-in-user-controls-with.html' title='Persisting Data in User Controls with ViewState'/><author><name>J²</name><uri>http://www.blogger.com/profile/14478332251437579476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://photos1.blogger.com/img/268/3041/1024/IMGP17751.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8924020273529189874.post-6358746456608494107</id><published>2009-01-21T09:49:00.000-08:00</published><updated>2009-01-21T09:53:44.386-08:00</updated><title type='text'>Asp.net DataObjectSource + Gridview difficulty</title><content type='html'>&lt;div&gt;Here are some annoyances I encountered recently while trying to get some basic data binding to work in ASP.NET:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;I was using an ObjectDataSource to access objects through our data access layer, and then displaying the data in a Gridview. After some tweaking, I got it to display all right, but when I clicked "Edit" and then "Update" I ran into all kinds of issues. First it wouldn't link up right to my data access layer, because it was looking for a method that included the Name and Description fields. After some digging around, I found out that the "Default" method it looks for is one with only an object (in this case of a type called TrackedEntity) as a parameter. But because the data access layer's default add/update/delete methods also include a boolean parameter to tell it whether or not to Save the updated changes (though I have a hard time imagining why you wouldn't want it to, if you're calling the Update method), ASP.NET got kicked out of this default object-oriented mode, and started looking instead for a method that took all the parameters it knew about, plus the ones that I specified. Fix: create an update method that only takes a TrackedEntity, and point the ObjectDataSource to that method.&lt;br /&gt;&lt;br /&gt;After this, however, it still couldn't update correctly because the TrackedEntity object it was updating was &lt;span style="font-style: italic; "&gt;only&lt;/span&gt; getting instantiated with its Name and Description (and not its ID). So when the data access layer tried loading up the object to update, it couldn't find an object with an ID of zero, so it died.&lt;br /&gt;&lt;br /&gt;As a work-around, I found that simply including the ID column in the GridView would do the trick, but that's a hack, at best. After much searching, I found out that GridViews have a DataKeyNames property, in which you can include a comma-separated list of fields that shouldn't be shown in a column, but which need to be persisted so that the object being saved gets instantiated with all its previous values.&lt;br /&gt;&lt;br /&gt;Finally, if I left any of the fields blank, it would complain that the values could not be null.  By default, Gridviews will convert empty strings to null values.  I had to put the following attribute in each BoundField: ConvertEmptyStringToNull="False".  Whew!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8924020273529189874-6358746456608494107?l=dotnetdom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dotnetdom.blogspot.com/feeds/6358746456608494107/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dotnetdom.blogspot.com/2009/01/aspnet-dataobjectsource-gridview.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8924020273529189874/posts/default/6358746456608494107'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8924020273529189874/posts/default/6358746456608494107'/><link rel='alternate' type='text/html' href='http://dotnetdom.blogspot.com/2009/01/aspnet-dataobjectsource-gridview.html' title='Asp.net DataObjectSource + Gridview difficulty'/><author><name>J²</name><uri>http://www.blogger.com/profile/14478332251437579476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://photos1.blogger.com/img/268/3041/1024/IMGP17751.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8924020273529189874.post-5721230627294284812</id><published>2009-01-21T09:41:00.000-08:00</published><updated>2009-01-21T09:49:04.731-08:00</updated><title type='text'>If programming languages were religions</title><content type='html'>Our company's CTO sent this to us after we had made the decision to switch to .NET and start using C# as our programming language on a new product we've started working on:&lt;div&gt;&lt;a href="http://www.aegisub.net/2008/12/if-programming-languages-were-religions.html"&gt;http://www.aegisub.net/2008/12/if-programming-languages-were-religions.html&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I thought it was pretty funny and appropriate, in light of my other, more personal blog, "&lt;a href="http://j2jensen.blogspot.com/"&gt;Adventures in Mormondom.&lt;/a&gt;"  Here's an excerpt:&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;/blockquote&gt;&lt;span class="Apple-style-span" style="color: rgb(51, 51, 51); font-family: Verdana; font-size: 13px; line-height: 16px; "&gt;&lt;p&gt;&lt;span style="font-weight: bold; "&gt;&lt;/span&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;span style="font-weight: bold; "&gt;C&lt;/span&gt; would be &lt;span style="font-weight: bold; "&gt;Judaism&lt;/span&gt; - it's old and restrictive, but most of the world is familiar with its laws and respects them. The catch is, you can't convert into it - you're either into it from the start, or you will think that it's insanity. Also, when things go wrong, many people are willing to blame the problems of the world on it.&lt;/p&gt;&lt;span class="fullpost" style="display: inline; "&gt;&lt;p&gt;&lt;span style="font-weight: bold; "&gt;Java&lt;/span&gt; would be &lt;span style="font-weight: bold; "&gt;Fundamentalist Christianity&lt;/span&gt; - it's theoretically based on C, but it voids so many of the old laws that it doesn't feel like the original at all. Instead, it adds its own set of rigid rules, which its followers believe to be far superior to the original. Not only are they certain that it's the best language in the world, but they're willing to burn those who disagree at the stake.&lt;/p&gt;&lt;p&gt;...&lt;/p&gt;&lt;p&gt;&lt;span style="font-weight: bold; "&gt;C#&lt;/span&gt; would be &lt;span style="font-weight: bold; "&gt;Mormonism&lt;/span&gt; - At first glance, it's the same as Java, but at a closer look you realize that it's controlled by a single corporation (which many Java followers believe to be evil), and that many theological concepts are quite different. You suspect that it'd probably be nice, if only all the followers of Java wouldn't discriminate so much against you for following it.&lt;br /&gt;&lt;/p&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8924020273529189874-5721230627294284812?l=dotnetdom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dotnetdom.blogspot.com/feeds/5721230627294284812/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dotnetdom.blogspot.com/2009/01/if-programming-languages-were-religions.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8924020273529189874/posts/default/5721230627294284812'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8924020273529189874/posts/default/5721230627294284812'/><link rel='alternate' type='text/html' href='http://dotnetdom.blogspot.com/2009/01/if-programming-languages-were-religions.html' title='If programming languages were religions'/><author><name>J²</name><uri>http://www.blogger.com/profile/14478332251437579476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://photos1.blogger.com/img/268/3041/1024/IMGP17751.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8924020273529189874.post-3837117693942971213</id><published>2009-01-21T09:39:00.000-08:00</published><updated>2009-01-21T09:41:46.388-08:00</updated><title type='text'>Introduction</title><content type='html'>At work, we're transitioning from Java technologies to .NET technologies. We've started a little project to help us get up to speed on .NET, and I have spent enough time on a couple of bugs that I figured I'd write about them to help anybody else who might run into similar problems.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I plan to use this blog as a place to post interesting things that I learn as we transition into .NET-dom.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8924020273529189874-3837117693942971213?l=dotnetdom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dotnetdom.blogspot.com/feeds/3837117693942971213/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dotnetdom.blogspot.com/2009/01/introduction.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8924020273529189874/posts/default/3837117693942971213'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8924020273529189874/posts/default/3837117693942971213'/><link rel='alternate' type='text/html' href='http://dotnetdom.blogspot.com/2009/01/introduction.html' title='Introduction'/><author><name>J²</name><uri>http://www.blogger.com/profile/14478332251437579476</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://photos1.blogger.com/img/268/3041/1024/IMGP17751.jpg'/></author><thr:total>0</thr:total></entry></feed>
