<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/atom.xsl" media="screen"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-US"><title type="html">Stuart Leeks</title><subtitle type="html">Stuart Leeks - Application Development Consultant</subtitle><id>http://blogs.msdn.com/stuartleeks/atom.xml</id><link rel="alternate" type="text/html" href="http://blogs.msdn.com/stuartleeks/default.aspx" /><link rel="self" type="application/atom+xml" href="http://blogs.msdn.com/stuartleeks/atom.xml" /><generator uri="http://communityserver.org" version="2.1.61025.2">Community Server</generator><updated>2008-08-27T23:35:00Z</updated><entry><title>T4MVC now with multiple file support</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/stuartleeks/archive/2009/11/17/t4mvc-now-with-multiple-file-support.aspx" /><id>http://blogs.msdn.com/stuartleeks/archive/2009/11/17/t4mvc-now-with-multiple-file-support.aspx</id><published>2009-11-17T09:03:20Z</published><updated>2009-11-17T09:03:20Z</updated><content type="html">&lt;p&gt;Ok, so I’m indulging in self-publicity a little with this post, but I really want to take the opportunity to highlight some great work that &lt;a href="http://blogs.msdn.com/davidebb/"&gt;David Ebbo&lt;/a&gt; has done. I’ve been spending a bit of time with &lt;a href="http://www.asp.net/mvc/"&gt;ASP.NET MVC Framework&lt;/a&gt; and really like it. The combination of testability, being led towards separation of concerns, massive amounts of extensibility and the way it aligns to HTTP all resonate quite strongly for me. I’m not saying for a minute that Web Forms is dead, but I do believe it is getting some serious competition from the MVC Framework! &lt;/p&gt;  &lt;p&gt;However, there has always been one area of the MVC Framework that just hasn’t sat well with me: magic strings. I.e. things for which the compiler doesn’t provide verification, refactoring won’t necessarily recognise, and intellisense provides no support! I’ve given a couple of examples below:&lt;/p&gt;  &lt;blockquote&gt;   &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;return &lt;/span&gt;View(&lt;span style="color: #a31515"&gt;&amp;quot;ResetSuccess&amp;quot;&lt;/span&gt;); &lt;span style="color: green"&gt;// render a non-default for this action&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="code"&gt;&lt;span style="background: #ffee62"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color: blue"&gt;= &lt;/span&gt;Html.ActionLink(&lt;span style="color: #a31515"&gt;&amp;quot;Details&amp;quot;&lt;/span&gt;, &lt;span style="color: #a31515"&gt;&amp;quot;ShowCustomer&amp;quot;&lt;/span&gt;, &lt;span style="color: blue"&gt;new &lt;/span&gt;{ customerID=&lt;span style="color: #a31515"&gt;&amp;quot;ABCDE&amp;quot; &lt;/span&gt;} )&lt;span style="background: #ffee62"&gt;%&amp;gt;&lt;/span&gt;&lt;/pre&gt;
  &lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/blockquote&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;In the examples above, “ResetSuccess” and “ShowCustomer” are used to refer to a view and an action respectively and are clearly magic strings. The “customerID” property on the anonymous type we’re creating is also essentially a magic string: the compiler can’t check that it actually matches a parameter on the action we are invoking. Fortunately there are ways around this. One way is to use the strongly typed helpers from the &lt;a href="http://aspnet.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=24471"&gt;MvcFutures&lt;/a&gt; project. These let you use syntax along the lines of&lt;/p&gt;

&lt;blockquote&gt;
  &lt;pre class="code"&gt;&lt;span style="background: #ffee62"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color: blue"&gt;= &lt;/span&gt;Html.ActionLink&amp;lt;CustomerController&amp;gt;(c =&amp;gt; c.ShowCustomer(&lt;span style="color: #a31515"&gt;&amp;quot;ABCDE&amp;quot;&lt;/span&gt;) )&lt;span style="background: #ffee62"&gt;%&amp;gt;&lt;/span&gt;&lt;/pre&gt;
  &lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/blockquote&gt;

&lt;p&gt;This does now give you compiler checking etc, but I’m not entirely sure about the syntax and there have been some questions raised around the performance (although I have to admit that I haven’t had chance to verify that).&lt;/p&gt;

&lt;p&gt;Another option (and the one that I’ve been using recently) is David’s T4MVC. You can download it from &lt;a href="http://aspnet.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=24471"&gt;here&lt;/a&gt; and read more about it on David’s blog &lt;a href="http://blogs.msdn.com/davidebb/archive/tags/T4MVC/default.aspx"&gt;here&lt;/a&gt;, but to revisit the previous examples using T4MVC:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;return &lt;/span&gt;View(&lt;span style="color: #2b91af"&gt;MVC&lt;/span&gt;.Home.ResetSuccess); &lt;span style="color: green"&gt;// render a non-default for this action&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="code"&gt;&lt;span style="background: #ffee62"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color: blue"&gt;= &lt;/span&gt;Html.ActionLink(&lt;span style="color: #a31515"&gt;&amp;quot;Details&amp;quot;&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;MVC&lt;/span&gt;.Customer.ShowCustomer(&lt;span style="color: #a31515"&gt;&amp;quot;ABCDE&amp;quot;&lt;/span&gt;) )&lt;span style="background: #ffee62"&gt;%&amp;gt;&lt;/span&gt;&lt;/pre&gt;
  &lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/blockquote&gt;

&lt;p&gt;I find this a really nice way to navigate through my controllers and views. It’s probably worth pointing out that it also works for referencing partial views, setting up routes, … essentially any place I’ve needed to refer to items in code it has helped me so far. I won’t spend a huge amount of time going through how this all works but I would encourage you to take a look at the code that gets generated. David has done some really neat stuff to ensure that it all works with intellisense/refactoring by deriving a new class from existing controllers and using a custom ActionResult to capture the action parameters etc. The latest &lt;a href="http://blogs.msdn.com/davidebb/archive/2009/11/16/t4mvc-2-5-00-update-multiple-output-files-and-minified-javascript-support.aspx"&gt;update&lt;/a&gt; has some minor changes by yours truly (although most of the work was already done thanks to &lt;a href="http://damieng.com/"&gt;Damien Guard&lt;/a&gt;’s &lt;a href="http://damieng.com/blog/2009/11/06/multiple-outputs-from-t4-made-easy-revisited"&gt;Multiple File Manager&lt;/a&gt;!) to allow you to generate separate files for each controller to make it easier to work with T4MVC in a team with multiple developers checking code out.&lt;/p&gt;

&lt;p&gt;Personally, I’m a huge fan of T4MVC and find that it provides a simple, discoverable way to reference views, actions etc. So, what are you waiting for? Go and &lt;a href="http://aspnet.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=24471"&gt;download it&lt;/a&gt; now!&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;UPDATE&lt;/strong&gt;: T4MVC now has its own homepage on codeplex: &lt;a title="http://aspnet.codeplex.com/wikipage?title=T4MVC" href="http://aspnet.codeplex.com/wikipage?title=T4MVC"&gt;http://aspnet.codeplex.com/wikipage?title=T4MVC&lt;/a&gt;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9923445" width="1" height="1"&gt;</content><author><name>stuartle</name><uri>http://blogs.msdn.com/members/stuartle.aspx</uri></author></entry><entry><title>Options for creating a test project</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/stuartleeks/archive/2009/08/20/options-for-creating-a-test-project.aspx" /><id>http://blogs.msdn.com/stuartleeks/archive/2009/08/20/options-for-creating-a-test-project.aspx</id><published>2009-08-20T20:10:46Z</published><updated>2009-08-20T20:10:46Z</updated><content type="html">&lt;p&gt;I was rooting through the Tools\Options dialog in Visual Studio recently and noticed the following options for Test projects:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/stuartleeks/WindowsLiveWriter/Optionsforcreatingatestproject_CCE5/image_4.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/blogfiles/stuartleeks/WindowsLiveWriter/Optionsforcreatingatestproject_CCE5/image_thumb_1.png" width="644" height="387" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Whilst these are probably reasonable defaults in terms of discoverability of features, I’ve always found that the first thing I did when creating a test project was to delete the introduction file and manual test (and sometimes the unit test, depending on what I’m doing). I’ve now unticked all of the options, so I get an empty project and just add what I need.&lt;/p&gt;  &lt;p&gt;It’s a small thing, but I like it!&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9877262" width="1" height="1"&gt;</content><author><name>stuartle</name><uri>http://blogs.msdn.com/members/stuartle.aspx</uri></author><category term="Visual Studio" scheme="http://blogs.msdn.com/stuartleeks/archive/tags/Visual+Studio/default.aspx" /></entry><entry><title>Setting the window title for a command prompt</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/stuartleeks/archive/2009/08/17/setting-the-window-title-for-a-command-prompt.aspx" /><id>http://blogs.msdn.com/stuartleeks/archive/2009/08/17/setting-the-window-title-for-a-command-prompt.aspx</id><published>2009-08-17T23:26:02Z</published><updated>2009-08-17T23:26:02Z</updated><content type="html">&lt;p&gt;Very quick tip in what seems to have become a mini-series (&lt;a href="http://blogs.msdn.com/stuartleeks/archive/2009/08/13/powershell-script-to-clean-and-zip-a-directory.aspx"&gt;Part 1&lt;/a&gt;, &lt;a href="http://blogs.msdn.com/stuartleeks/archive/2009/08/17/finding-files-in-your-path-environment.aspx"&gt;Part 2&lt;/a&gt;). I often find myself with a number of command windows open and switching between them can be problematic. To address this I use the “title” command to set the window title, and have found that setting the title to match the current directory works well. To achieve this quickly you can use the following command&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font face="Courier New"&gt;@title %CD%&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;And, of course, you can wrap this in a batch file and put it in your path to make it easier to remember and use.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9872851" width="1" height="1"&gt;</content><author><name>stuartle</name><uri>http://blogs.msdn.com/members/stuartle.aspx</uri></author><category term="Utilities" scheme="http://blogs.msdn.com/stuartleeks/archive/tags/Utilities/default.aspx" /><category term="Batch file" scheme="http://blogs.msdn.com/stuartleeks/archive/tags/Batch+file/default.aspx" /></entry><entry><title>Finding files in your path environment</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/stuartleeks/archive/2009/08/17/finding-files-in-your-path-environment.aspx" /><id>http://blogs.msdn.com/stuartleeks/archive/2009/08/17/finding-files-in-your-path-environment.aspx</id><published>2009-08-17T23:24:16Z</published><updated>2009-08-17T23:24:16Z</updated><content type="html">&lt;p&gt;&lt;/p&gt;  &lt;p&gt;Occasionally I’m working at the command prompt and have a utility that is in the path environment, but need to find where the file actually is. So, I wrote a little batch file that does exactly that&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font face="Courier New"&gt;@echo off        &lt;br /&gt;echo Searching path for %1         &lt;br /&gt;if &amp;quot;%~$PATH:1&amp;quot;==&amp;quot;&amp;quot; goto :notfound         &lt;br /&gt;echo Found: %~$PATH:1         &lt;br /&gt;goto :end &lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;:notfound        &lt;br /&gt;echo Unable to find %1         &lt;br /&gt;goto :end &lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;:end&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;The batch file takes a single argument which is the filename to find. The magic happens in the &amp;quot;%~$PATH:1&amp;quot; part – this basically searches the directories in the &lt;a href="http://technet.microsoft.com/en-us/library/bb490963.aspx"&gt;PATH&lt;/a&gt; environment variable for first argument passed to the batch file. All of the rest of the batch file is geared towards producing nice output!&lt;/p&gt;  &lt;p&gt;NOTE – use this at your own risk. If it deletes all of your files or replaces the text of your important documents with &lt;a href="http://www.lipsum.com/"&gt;Lorem Ipsum&lt;/a&gt; then you didn’t get it from me!&lt;/p&gt;  &lt;p&gt;NOTE 2 – if you want to find out about the other expansion options for environment variables then type “HELP FOR” at the command prompt.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;** UPDATE 2009/08/20 **&lt;/strong&gt;:&lt;/p&gt;  &lt;p&gt;It turns out that there’s a better way to do this: the &lt;a href="http://technet.microsoft.com/en-us/library/cc753148(WS.10).aspx"&gt;WHERE&lt;/a&gt; command – thanks &lt;a href="http://phazed.com/"&gt;Rupert&lt;/a&gt;!&lt;/p&gt;  &lt;p&gt;The WHERE command will list all locations that it found a match in the path, also allows wildcards and is generally more flexible. Time to delete that batch file... &lt;/p&gt;  &lt;p&gt;I’m not sure when this command appeared. It is listed in the command-line reference for &lt;a href="http://technet.microsoft.com/en-us/library/cc754340(WS.10).aspx"&gt;Windows Vista&lt;/a&gt;, but not for &lt;a href="http://technet.microsoft.com/en-us/library/bb490890.aspx"&gt;Windows XP&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9872847" width="1" height="1"&gt;</content><author><name>stuartle</name><uri>http://blogs.msdn.com/members/stuartle.aspx</uri></author></entry><entry><title>PowerShell script to clean and zip a directory</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/stuartleeks/archive/2009/08/13/powershell-script-to-clean-and-zip-a-directory.aspx" /><id>http://blogs.msdn.com/stuartleeks/archive/2009/08/13/powershell-script-to-clean-and-zip-a-directory.aspx</id><published>2009-08-14T00:14:37Z</published><updated>2009-08-14T00:14:37Z</updated><content type="html">&lt;p&gt;As part of my role I’m often sending sample code to customers. Sometimes this is a small snippet inline in an email, but often it will be a zipped up Visual Studio solution. Simply zipping up the folder as-is ends up including bin and obj directories which bloat the zip. Performing a clean in Visual Studio helps, but I ended up writing a PowerShell script to perform the directory clean. It turned out to be reasonably simply to put together:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font face="Courier New"&gt;Get-ChildItem . -recurse -force -include bin,obj,*.tmp,*.user,*.sqlsuo,*.vssscc,*.vspscc,_UpgradeReport_Files | foreach -process {Remove-Item $_.FullName -Force -Recurse}&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;The command performs a recursive clean starting from the current directory and removes files and directories that I’m generally not interested in including in the zip file. So far this has made a massive difference to the size of zip files that I’ve sent. Although this has proved to be a useful script, I recently spent some time updating it to perform the directory zipping. This turned out to be a little trickier and I ended up pulling snippets together from a number of sources on the internet.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font face="Courier New"&gt;$Directory = Get-Item .        &lt;br /&gt;$ParentDirectory = Get-Item ..         &lt;br /&gt;$ZipFileName = $ParentDirectory.FullName + &amp;quot;\&amp;quot; + $Directory.Name + &amp;quot;.zip&amp;quot; &lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;if (test-path $ZipFileName) {        &lt;br /&gt;&amp;#160; echo &amp;quot;Zip file already exists at $ZipFileName&amp;quot;         &lt;br /&gt;&amp;#160; return         &lt;br /&gt;} &lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;set-content $ZipFileName (&amp;quot;PK&amp;quot; + [char]5 + [char]6 + (&amp;quot;$([char]0)&amp;quot; * 18))        &lt;br /&gt;(dir $ZipFileName).IsReadOnly = $false &lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;$ZipFile = (new-object -com shell.application).NameSpace($ZipFileName) &lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;$ZipFile.CopyHere($Directory.FullName)&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;The first few lines of this snippet set up a couple of variables to make life easier later. Then it tests if the zip already exists and bails out if so. Then we get on to the interesting task of creating the zip file using a combination of directly to the file and calling the &lt;a href="http://msdn.microsoft.com/en-us/library/bb774094(VS.85).aspx"&gt;Shell.Application&lt;/a&gt; object.&lt;/p&gt;  &lt;p&gt;You can either save these as separate scripts, or combine them into a single script. Note that I’m still trying to convert to PowerShell after far too long writing batch files so I make no claims that this is the best way to write a PowerShell script. In fact I make no claims about this, so use with caution in case it deletes the document you spent all night finishing or wipes your hard drive. &lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9868824" width="1" height="1"&gt;</content><author><name>stuartle</name><uri>http://blogs.msdn.com/members/stuartle.aspx</uri></author><category term="Utilities" scheme="http://blogs.msdn.com/stuartleeks/archive/tags/Utilities/default.aspx" /><category term="PowerShell" scheme="http://blogs.msdn.com/stuartleeks/archive/tags/PowerShell/default.aspx" /></entry><entry><title>Quickly creating an Outlook rule</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/stuartleeks/archive/2009/08/13/quickly-creating-an-outlook-rule.aspx" /><id>http://blogs.msdn.com/stuartleeks/archive/2009/08/13/quickly-creating-an-outlook-rule.aspx</id><published>2009-08-13T23:35:05Z</published><updated>2009-08-13T23:35:05Z</updated><content type="html">&lt;p&gt;I’ve had a couple of conversations with people recently where they’ve said that they keep meaning to set up an Outlook rule to move specific messages to a separate folder. On each occasion the need to navigate the Tools\Rules And Alerts window seems to have been enough to put the task off. Unfortunately, they weren’t aware that you can right click on a message and choose Create Rule. This brings up a simpler dialog that contains pre-completed options based on the message you had selected (e.g. messages from this sender, with this subject, …) which is my preferred way of creating rules! Official documentation: &lt;a title="http://office.microsoft.com/en-us/outlook/HA100968031033.aspx#4" href="http://office.microsoft.com/en-us/outlook/HA100968031033.aspx#4"&gt;http://office.microsoft.com/en-us/outlook/HA100968031033.aspx#4&lt;/a&gt;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9868780" width="1" height="1"&gt;</content><author><name>stuartle</name><uri>http://blogs.msdn.com/members/stuartle.aspx</uri></author><category term="Outlook" scheme="http://blogs.msdn.com/stuartleeks/archive/tags/Outlook/default.aspx" /></entry><entry><title>Adding links containing spaces to an email message</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/stuartleeks/archive/2009/08/07/adding-links-containing-spaces-to-an-email-message.aspx" /><id>http://blogs.msdn.com/stuartleeks/archive/2009/08/07/adding-links-containing-spaces-to-an-email-message.aspx</id><published>2009-08-07T10:22:00Z</published><updated>2009-08-07T10:22:00Z</updated><content type="html">&lt;P&gt;Possibly slightly off-topic for this blog, but so far I’m doing quite a good job of not settling down on a single topic ;-)&lt;/P&gt;
&lt;P&gt;Outlook has the nice feature that if you type something that looks like a link into an email, it will automatically create the link for you. Now, suppose you have a share on a server: “\\server\Some Share” (without the quotes). If you simply type this in, Outlook is confused by the space and you end up with&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;IMG style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=image border=0 alt=image src="http://blogs.msdn.com/blogfiles/stuartleeks/WindowsLiveWriter/Addinglinkscontainingspacestoanemailmess_AD99/image_9.png" width=157 height=36 mce_src="http://blogs.msdn.com/blogfiles/stuartleeks/WindowsLiveWriter/Addinglinkscontainingspacestoanemailmess_AD99/image_9.png"&gt; &lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Fortunately there is a simply workaround. Unfortunately, very few people seem to be aware of it! All you need to do is enclose the link text in angle brackets. So you’d actually type “&amp;lt;\\server\Some Share&amp;gt;”&amp;nbsp;(without the quotes). Now when Outlook creates the link, it uses the full text between the brackets:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;IMG style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=image border=0 alt=image src="http://blogs.msdn.com/blogfiles/stuartleeks/WindowsLiveWriter/Addinglinkscontainingspacestoanemailmess_AD99/image_10.png" width=151 height=30 mce_src="http://blogs.msdn.com/blogfiles/stuartleeks/WindowsLiveWriter/Addinglinkscontainingspacestoanemailmess_AD99/image_10.png"&gt; &lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;And that’s it! Now start using it, and tell everyone else about it. You can always point them to the &lt;A href="http://office.microsoft.com/en-us/outlook/HA100857971033.aspx?pid=CH100776981033" mce_href="http://office.microsoft.com/en-us/outlook/HA100857971033.aspx?pid=CH100776981033"&gt;official write-up&lt;/A&gt; if you’d rather.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9859950" width="1" height="1"&gt;</content><author><name>stuartle</name><uri>http://blogs.msdn.com/members/stuartle.aspx</uri></author><category term="Outlook" scheme="http://blogs.msdn.com/stuartleeks/archive/tags/Outlook/default.aspx" /></entry><entry><title>ADPlus, Windows 7 and ASP.Net</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/stuartleeks/archive/2009/07/22/adplus-windows-7-and-asp-net.aspx" /><id>http://blogs.msdn.com/stuartleeks/archive/2009/07/22/adplus-windows-7-and-asp-net.aspx</id><published>2009-07-22T18:11:15Z</published><updated>2009-07-22T18:11:15Z</updated><content type="html">&lt;p&gt;I’ve been working through some crash dumps with &lt;a href="http://msdn.microsoft.com/en-us/library/cc265629.aspx"&gt;ADPlus&lt;/a&gt; and &lt;a href="http://msdn.microsoft.com/en-us/library/cc266321.aspx"&gt;WinDBG&lt;/a&gt; recently and hit a couple of snags that seem to be related to running ADPlus on Windows 7. &lt;a href="http://www.wintellect.com/CS/blogs/jrobbins/default.aspx"&gt;John Robbins&lt;/a&gt; gives &lt;a href="http://www.wintellect.com/CS/blogs/jrobbins/archive/2009/02/02/fixed-adplus-that-works-with-windows-7-and-probably-s2k8-r2.aspx"&gt;details&lt;/a&gt; of the first issue I hit and points out that the output from tlist.exe (which ADPlus uses) had changed. The post also notes that the issue is fixed in later releases of the &lt;a href="http://www.microsoft.com/whdc/devtools/debugging/default.mspx"&gt;Debugging Tools&lt;/a&gt; (version 6.11.1.402 and later), so I upgraded. With 6.11.1.404 installed, I started to get a different error: &lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font face="Courier New"&gt;Microsoft (R) Windows Script Host Version 5.8        &lt;br /&gt;Copyright (C) Microsoft Corporation. All rights reserved. &lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;Attaching the debugger to: W3WP.EXE_-MyAppPool-_-v_-v2.0-_-l_-webengine4.dll-_-a_-.-pipe-iisipm1417f766-136f-4838-8332-861176da3119_-h_-C-inetpub-temp-apppools-MyAppPool.config-_-w_--_-m_0_-t_20        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; (Process ID: 3412)         &lt;br /&gt;Error creating file: C:\Program Files\Debugging Tools for Windows (x64)\Hang_Mode__Date_07-22-2009__Time_15-32-0505\CDBScripts\PID-3412__W3WP.EXE_-MyAppPool-_-v_-v2.0-_-l_-webengine4.dll-_-a_-.-pipe-iisipm1417f766-136f-4838-8332-861176da3119_-h_-C-inetpub-temp-apppools-MyAppPool.config-_-w_--_-m_0_-t_20.cfg Error: 76 -         &lt;br /&gt;Path not found&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;On a successful run, I’d expect to see&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font face="Courier New"&gt;Microsoft (R) Windows Script Host Version 5.8        &lt;br /&gt;Copyright (C) Microsoft Corporation. All rights reserved. &lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font face="Courier New"&gt;Attaching the debugger to: W3WP.EXE_MyAppPool        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; (Process ID: 3412)&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;The key difference is the text after “Attaching the debugger to:”. Looking through the adplus script, the name used there is built up from the process name and the application pool name. In order to get the name of the application pool, adplus uses the command line from the tlist output. &lt;/p&gt;  &lt;p&gt;On my machine (and also on a colleague’s Windows 7 machine) the command line for w3wp.exe is along the lines of&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font face="Courier New"&gt;c:\windows\system32\inetsrv\w3wp.exe -ap &amp;quot;MyAppPool&amp;quot; -v &amp;quot;v2.0&amp;quot; -l &amp;quot;webengine4.dll&amp;quot; -a \\.\pipe\iisipm1417f766-136f-4838-8332-861176da3119 -h&amp;quot;C:\inetpub\temp\apppools\MyAppPool.config&amp;quot; -w &amp;quot;&amp;quot; -m 0 -t 20&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;On a Windows Server 2008 box that I had access to the command line is similar, but the big difference is that the –ap parameter (which specifies the application pool name) appears at the end of the command line. Looking back at the adplus script, it seems to assume that the –ap parameter will be at the end. I made a small change to my adplus script to only pull back the quoted value (with no regard for how to handle embedded quotes). The point to make the change is after the following code&lt;/p&gt;  &lt;blockquote&gt;   &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;g_CurrentProcesses(PCount).Name = &lt;span style="color: #a31515"&gt;&amp;quot;W3WP.EXE&amp;quot; &lt;/span&gt;&lt;span style="color: blue"&gt;Then
    &lt;/span&gt;&lt;span style="color: green"&gt;' read the next line
    &lt;/span&gt;&lt;span style="color: blue"&gt;if not &lt;/span&gt;objTextFile.AtEndofStream &lt;span style="color: blue"&gt;Then
        &lt;/span&gt;strAux = objTextFile.ReadLine
        &lt;span style="color: green"&gt;' check the command line for the -ap parameter
        &lt;/span&gt;&lt;span style="color: blue"&gt;If &lt;/span&gt;InStr(strAux, &lt;span style="color: #a31515"&gt;&amp;quot;-ap&amp;quot;&lt;/span&gt;) &lt;span style="color: blue"&gt;Then
            &lt;/span&gt;arrAux = split(strAux, &lt;span style="color: #a31515"&gt;&amp;quot;-ap&amp;quot;&lt;/span&gt;, -1, 1)
            strPackageName = trim(arrAux(1))&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;All that is needed is to add the following code immediately after the last line above (NOTE: as always, use this entirely at your own risk!!!)&lt;/p&gt;

&lt;blockquote&gt;
  &lt;pre class="code"&gt;&lt;span style="color: green"&gt;' modifications start (&lt;/span&gt;&lt;span style="color: green"&gt;http://blogs.msdn.com/stuartleeks/archive/2009/07/22/adplus-windows-7-and-asp-net.aspx&lt;a href="http://blogs.msdn.com/stuartleeks)If"&gt;)
&lt;/span&gt;&lt;span style="color: blue"&gt;If&lt;/a&gt; &lt;/span&gt;Mid(strPackageName, 1, 1) = &lt;span style="color: #a31515"&gt;&amp;quot;&amp;quot;&amp;quot;&amp;quot; &lt;/span&gt;&lt;span style="color: blue"&gt;Then
    &lt;/span&gt;strPackagename = Mid(strPackageName, 2, InStr(2,strPackageName, &lt;span style="color: #a31515"&gt;&amp;quot;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;) - 2)
&lt;span style="color: blue"&gt;End If
&lt;/span&gt;&lt;span style="color: green"&gt;' modifications end&lt;/span&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;With this change in place, I’m back in business with adplus! As mentioned, I got this behaviour on my Windows 7 machine using version 6.11.1.404 of the Debugging Tools for Windows. I make no claims that the change above will work for you, or even that it won’t delete all your files ;-). Hopefully this will be addressed in a future release of the Debugging Tools…&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9844891" width="1" height="1"&gt;</content><author><name>stuartle</name><uri>http://blogs.msdn.com/members/stuartle.aspx</uri></author><category term="Debugging" scheme="http://blogs.msdn.com/stuartleeks/archive/tags/Debugging/default.aspx" /></entry><entry><title>Improving ObjectQuery&lt;T&gt;.Include – Updated</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/stuartleeks/archive/2009/04/24/improving-objectquery-t-include-updated.aspx" /><id>http://blogs.msdn.com/stuartleeks/archive/2009/04/24/improving-objectquery-t-include-updated.aspx</id><published>2009-04-24T17:25:00Z</published><updated>2009-04-24T17:25:00Z</updated><content type="html">&lt;P&gt;Having spent some time using the sample from my &lt;A href="http://blogs.msdn.com/stuartleeks/archive/2008/08/27/improving-objectquery-t-include.aspx" mce_href="http://blogs.msdn.com/stuartleeks/archive/2008/08/27/improving-objectquery-t-include.aspx"&gt;previous post&lt;/A&gt; on ObjectQuery.Include, I’ve encountered a bug! It turns out that the code generates the wrong include string for &lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE class=code&gt;context.Customers.Include(c =&amp;gt; c.Order.SubInclude(o=&amp;gt;o.OrderDetail))&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;The fix for this is a small change to the BuildString method to recurse up the MemberExpression if necessary. The updated code is below&amp;nbsp; - usual disclaimers apply!&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;    public static class &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;ObjectQueryExtensions
    &lt;/SPAN&gt;{
        &lt;SPAN style="COLOR: blue"&gt;public static &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;ObjectQuery&lt;/SPAN&gt;&amp;lt;TSource&amp;gt; Include&amp;lt;TSource, TPropType&amp;gt;(&lt;SPAN style="COLOR: blue"&gt;this &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;ObjectQuery&lt;/SPAN&gt;&amp;lt;TSource&amp;gt; source, &lt;SPAN style="COLOR: #2b91af"&gt;Expression&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: #2b91af"&gt;Func&lt;/SPAN&gt;&amp;lt;TSource, TPropType&amp;gt;&amp;gt; propertySelector)
        {
            &lt;SPAN style="COLOR: blue"&gt;string &lt;/SPAN&gt;includeString = BuildString(propertySelector);
            &lt;SPAN style="COLOR: blue"&gt;return &lt;/SPAN&gt;source.Include(includeString);
        }
        &lt;SPAN style="COLOR: blue"&gt;private static string &lt;/SPAN&gt;BuildString(&lt;SPAN style="COLOR: #2b91af"&gt;Expression &lt;/SPAN&gt;propertySelector)
        {
            &lt;SPAN style="COLOR: blue"&gt;switch &lt;/SPAN&gt;(propertySelector.NodeType)
            {
                &lt;SPAN style="COLOR: blue"&gt;case &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;ExpressionType&lt;/SPAN&gt;.Lambda:
                    &lt;SPAN style="COLOR: #2b91af"&gt;LambdaExpression &lt;/SPAN&gt;lambdaExpression = (&lt;SPAN style="COLOR: #2b91af"&gt;LambdaExpression&lt;/SPAN&gt;)propertySelector;
                    &lt;SPAN style="COLOR: blue"&gt;return &lt;/SPAN&gt;BuildString(lambdaExpression.Body);

                &lt;SPAN style="COLOR: blue"&gt;case &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;ExpressionType&lt;/SPAN&gt;.Quote:
                    &lt;SPAN style="COLOR: #2b91af"&gt;UnaryExpression &lt;/SPAN&gt;unaryExpression = (&lt;SPAN style="COLOR: #2b91af"&gt;UnaryExpression&lt;/SPAN&gt;)propertySelector;
                    &lt;SPAN style="COLOR: blue"&gt;return &lt;/SPAN&gt;BuildString(unaryExpression.Operand);

                &lt;SPAN style="COLOR: blue"&gt;case &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;ExpressionType&lt;/SPAN&gt;.MemberAccess:

                    &lt;SPAN style="COLOR: #2b91af"&gt;MemberExpression &lt;/SPAN&gt;memberExpression = (&lt;SPAN style="COLOR: #2b91af"&gt;MemberExpression&lt;/SPAN&gt;)propertySelector;
                    &lt;SPAN style="COLOR: #2b91af"&gt;MemberInfo &lt;/SPAN&gt;propertyInfo = memberExpression.Member;

                    &lt;SPAN style="COLOR: blue"&gt;if &lt;/SPAN&gt;(memberExpression.Expression &lt;SPAN style="COLOR: blue"&gt;is &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;ParameterExpression&lt;/SPAN&gt;)
                    {
                        &lt;SPAN style="COLOR: blue"&gt;return &lt;/SPAN&gt;propertyInfo.Name;
                    }
                    &lt;SPAN style="COLOR: blue"&gt;else
                    &lt;/SPAN&gt;{
                        &lt;SPAN style="COLOR: green"&gt;// we've got a nested property (e.g. MyType.SomeProperty.SomeNestedProperty)
                        &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;return &lt;/SPAN&gt;BuildString(memberExpression.Expression) + &lt;SPAN style="COLOR: #a31515"&gt;"." &lt;/SPAN&gt;+ propertyInfo.Name;
                    }

                &lt;SPAN style="COLOR: blue"&gt;case &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;ExpressionType&lt;/SPAN&gt;.Call:
                    &lt;SPAN style="COLOR: #2b91af"&gt;MethodCallExpression &lt;/SPAN&gt;methodCallExpression = (&lt;SPAN style="COLOR: #2b91af"&gt;MethodCallExpression&lt;/SPAN&gt;)propertySelector;
                    &lt;SPAN style="COLOR: blue"&gt;if &lt;/SPAN&gt;(IsSubInclude(methodCallExpression.Method)) &lt;SPAN style="COLOR: green"&gt;// check that it's a SubInclude call
                    &lt;/SPAN&gt;{
                        &lt;SPAN style="COLOR: green"&gt;// argument 0 is the expression to which the SubInclude is applied (this could be member access or another SubInclude)
                        // argument 1 is the expression to apply to get the included property
                        // Pass both to BuildString to get the full expression
                        &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;return &lt;/SPAN&gt;BuildString(methodCallExpression.Arguments[0]) + &lt;SPAN style="COLOR: #a31515"&gt;"." &lt;/SPAN&gt;+
                               BuildString(methodCallExpression.Arguments[1]);
                    }
                    &lt;SPAN style="COLOR: green"&gt;// else drop out and throw
                    &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;break&lt;/SPAN&gt;;
            }
            &lt;SPAN style="COLOR: blue"&gt;throw new &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;InvalidOperationException&lt;/SPAN&gt;(&lt;SPAN style="COLOR: #a31515"&gt;"Expression must be a member expression or an SubInclude call: " &lt;/SPAN&gt;+ propertySelector.ToString());

        }

        &lt;SPAN style="COLOR: blue"&gt;private static readonly &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;MethodInfo&lt;/SPAN&gt;[] SubIncludeMethods;
        &lt;SPAN style="COLOR: blue"&gt;static &lt;/SPAN&gt;ObjectQueryExtensions()
        {
            &lt;SPAN style="COLOR: #2b91af"&gt;Type &lt;/SPAN&gt;type = &lt;SPAN style="COLOR: blue"&gt;typeof&lt;/SPAN&gt;(&lt;SPAN style="COLOR: #2b91af"&gt;ObjectQueryExtensions&lt;/SPAN&gt;);
            SubIncludeMethods = type.GetMethods().Where(mi =&amp;gt; mi.Name == &lt;SPAN style="COLOR: #a31515"&gt;"SubInclude"&lt;/SPAN&gt;).ToArray();
        }
        &lt;SPAN style="COLOR: blue"&gt;private static bool &lt;/SPAN&gt;IsSubInclude(&lt;SPAN style="COLOR: #2b91af"&gt;MethodInfo &lt;/SPAN&gt;methodInfo)
        {
            &lt;SPAN style="COLOR: blue"&gt;if &lt;/SPAN&gt;(methodInfo.IsGenericMethod)
            {
                &lt;SPAN style="COLOR: blue"&gt;if &lt;/SPAN&gt;(!methodInfo.IsGenericMethodDefinition)
                {
                    methodInfo = methodInfo.GetGenericMethodDefinition();
                }
            }
            &lt;SPAN style="COLOR: blue"&gt;return &lt;/SPAN&gt;SubIncludeMethods.Contains(methodInfo);
        }

        &lt;SPAN style="COLOR: blue"&gt;public static &lt;/SPAN&gt;TPropType SubInclude&amp;lt;TSource, TPropType&amp;gt;(&lt;SPAN style="COLOR: blue"&gt;this &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;EntityCollection&lt;/SPAN&gt;&amp;lt;TSource&amp;gt; source, &lt;SPAN style="COLOR: #2b91af"&gt;Expression&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: #2b91af"&gt;Func&lt;/SPAN&gt;&amp;lt;TSource, TPropType&amp;gt;&amp;gt; propertySelector)
            &lt;SPAN style="COLOR: blue"&gt;where &lt;/SPAN&gt;TSource : &lt;SPAN style="COLOR: blue"&gt;class&lt;/SPAN&gt;, &lt;SPAN style="COLOR: #2b91af"&gt;IEntityWithRelationships
            &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;where &lt;/SPAN&gt;TPropType : &lt;SPAN style="COLOR: blue"&gt;class
        &lt;/SPAN&gt;{
            &lt;SPAN style="COLOR: blue"&gt;throw new &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;InvalidOperationException&lt;/SPAN&gt;(&lt;SPAN style="COLOR: #a31515"&gt;"This method is only intended for use with ObjectQueryExtensions.Include to generate expressions trees"&lt;/SPAN&gt;); &lt;SPAN style="COLOR: green"&gt;// no actually using this - just want the expression!
        &lt;/SPAN&gt;}
        &lt;SPAN style="COLOR: blue"&gt;public static &lt;/SPAN&gt;TPropType SubInclude&amp;lt;TSource, TPropType&amp;gt;(&lt;SPAN style="COLOR: blue"&gt;this &lt;/SPAN&gt;TSource source, &lt;SPAN style="COLOR: #2b91af"&gt;Expression&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: #2b91af"&gt;Func&lt;/SPAN&gt;&amp;lt;TSource, TPropType&amp;gt;&amp;gt; propertySelector)
            &lt;SPAN style="COLOR: blue"&gt;where &lt;/SPAN&gt;TSource : &lt;SPAN style="COLOR: blue"&gt;class&lt;/SPAN&gt;, &lt;SPAN style="COLOR: #2b91af"&gt;IEntityWithRelationships
            &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;where &lt;/SPAN&gt;TPropType : &lt;SPAN style="COLOR: blue"&gt;class
        &lt;/SPAN&gt;{
            &lt;SPAN style="COLOR: blue"&gt;throw new &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;InvalidOperationException&lt;/SPAN&gt;(&lt;SPAN style="COLOR: #a31515"&gt;"This method is only intended for use with ObjectQueryExtensions.Include to generate expressions trees"&lt;/SPAN&gt;); &lt;SPAN style="COLOR: green"&gt;// no actually using this - just want the expression!
        &lt;/SPAN&gt;}
    }&lt;/PRE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9566779" width="1" height="1"&gt;</content><author><name>stuartle</name><uri>http://blogs.msdn.com/members/stuartle.aspx</uri></author><category term="LINQ" scheme="http://blogs.msdn.com/stuartleeks/archive/tags/LINQ/default.aspx" /><category term="Extension methods" scheme="http://blogs.msdn.com/stuartleeks/archive/tags/Extension+methods/default.aspx" /></entry><entry><title>Cheating at Scrabble with LINQ to Objects</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/stuartleeks/archive/2009/03/05/cheating-at-scrabble-with-linq-to-objects.aspx" /><id>http://blogs.msdn.com/stuartleeks/archive/2009/03/05/cheating-at-scrabble-with-linq-to-objects.aspx</id><published>2009-03-06T00:33:04Z</published><updated>2009-03-06T00:33:04Z</updated><content type="html">&lt;p&gt;I read an interesting &lt;a href="http://blogs.msdn.com/ericlippert/archive/2009/02/04/a-nasality-talisman-for-the-sultana-analyst.aspx"&gt;post&lt;/a&gt; on &lt;a href="http://blogs.msdn.com/ericlippert/default.aspx"&gt;Eric Lippert’s blog&lt;/a&gt; recently where he was using LINQ to Objects to find possible words from a set of letters in Scrabble (he wasn’t actually cheating – that just makes for a more interesting title!). Eric made a great &lt;a href="http://blogs.msdn.com/ericlippert/archive/2009/02/06/santalic-tailfans-part-two.aspx"&gt;follow-up post&lt;/a&gt; that highlights the need for both defining performance goals and for profiling when working to improve performance. I thoroughly recommend reading both Eric’s posts because they are great posts - plus they set the scene for this post ;-). In Eric’s posts, he noted that he’d met his performance goals for the code but having taken a copy of the code and started to play with it, I became the new user. I guess that I can be a little impatient at times and wanted it to feel as though the results were returned instantly! I stuck with Eric’s decision to not simply cache the dictionary in memory – after all, I may want to use a dictionary that won’t fit into memory at some point. &lt;/p&gt;  &lt;p&gt;Running the profiler against the code on my machine shows that even before the modifications in Eric’s second post, reading the data from disk is the bottleneck on my machine. This highlights another issue with profiling your application: you need to perform the profiling on representative hardware. In my case I’m running the application on a laptop so it may be that my hard drive is slower. Having said that, the changes from Eric’s post still made a noticeable difference to performance:&lt;/p&gt;  &lt;table border="0" cellspacing="0" cellpadding="2" width="350"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td valign="top" width="197"&gt;&lt;strong&gt;Method&lt;/strong&gt;&lt;/td&gt;        &lt;td valign="top" width="151"&gt;&lt;strong&gt;Search time(ms)&lt;/strong&gt;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="212"&gt;Original&lt;/td&gt;        &lt;td valign="top" width="157"&gt;2700&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="215"&gt;Updated&lt;/td&gt;        &lt;td valign="top" width="159"&gt;1658&lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;Having determined that reading from disk is the culprit (at least on my machine!), I looked through the code again. In the original code, the SearchDictionary method is called once with the original rack and then 26 further times as a result of adding an extra letter to the rack (to allow matching to existing tiles on the board). &lt;/p&gt;  &lt;p&gt;First off, I refactored the code slightly and introduced a SearchResult class&lt;/p&gt;  &lt;blockquote&gt;   &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;SearchResult
&lt;/span&gt;{
    &lt;span style="color: blue"&gt;public string &lt;/span&gt;Rack { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }
    &lt;span style="color: blue"&gt;public &lt;/span&gt;&lt;span style="color: #2b91af"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;string&lt;/span&gt;&amp;gt; Words { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }
}&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;This allows my Search method to return an IEnumerable&amp;lt;SearchResult&amp;gt; that includes the original rack plus the virtual racks formed by using a letter from the board. My implementation of the SearchDictionary method now handles searching with the additional letters. With this change in place I can now update the search method so that it only hits the file once. Without boring you with the details too much, I could have just added the extra items to the HashSet that Eric added in his second post but I wanted to be able to correlate the matches with the original rack for outputting the results (essentially I constrained myself to producing the same output as the original method). I created a type to correlate the original and expanded/canonicalised rack info (called RackInfo) and set up a dictionary keyed on the rack value after expansion for placeholders and canonicalisation. This dictionary can then replace the HashSet.&lt;/p&gt;

&lt;p&gt;The original LINQ to Objects query to perform the matching was&lt;/p&gt;

&lt;blockquote&gt;
  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;from &lt;/span&gt;line &lt;span style="color: blue"&gt;in &lt;/span&gt;FileLines(DictionaryFilename)
&lt;span style="color: blue"&gt;where &lt;/span&gt;line.Length == originalRack.Length
&lt;span style="color: blue"&gt;where &lt;/span&gt;racks.Contains(Canonicalize(line))
&lt;span style="color: blue"&gt;select &lt;/span&gt;line;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;Since we’re working with the original rack and the rack combined with additional letters, the line length clause needs a minor tweak. The racks.Contains also needs tweaking to use ContainsKey. Other than that, the main part of the query remains unchanged! &lt;/p&gt;

&lt;blockquote&gt;
  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;from &lt;/span&gt;line &lt;span style="color: blue"&gt;in &lt;/span&gt;FileLines(DictionaryFilename)
&lt;span style="color: blue"&gt;where &lt;/span&gt;line.Length == originalRack.Length || line.Length == originalRack.Length+1
&lt;span style="color: blue"&gt;where &lt;/span&gt;groupedRackInfos.ContainsKey(Canonicalize(line))
&lt;span style="color: blue"&gt;select new &lt;/span&gt;{ Word = line, OriginalRacks = groupedRackInfos[Canonicalize(line)] };&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;Notice that the results of this query is an IEnumerable that returns each matched word along with the racks that produced a match for that word. The results need to be re-shaped back into the matches for each rack, but even with this small amount of extra work (done with LINQ to Objects, naturally!) the timings speak for themselves:&lt;/p&gt;

&lt;table border="0" cellspacing="0" cellpadding="2" width="350"&gt;&lt;tbody&gt;
    &lt;tr&gt;
      &lt;td valign="top" width="197"&gt;&lt;strong&gt;Method&lt;/strong&gt;&lt;/td&gt;

      &lt;td valign="top" width="151"&gt;&lt;strong&gt;Search time(ms)&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="top" width="212"&gt;Original&lt;/td&gt;

      &lt;td valign="top" width="157"&gt;2700&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="top" width="215"&gt;Updated&lt;/td&gt;

      &lt;td valign="top" width="159"&gt;1658&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="top" width="215"&gt;Single file pass&lt;/td&gt;

      &lt;td valign="top" width="159"&gt;108&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;Not a bad result. In fact, it feels near enough to instantaneous to me so I’m calling it a day on this one!&lt;/p&gt;

&lt;p&gt;I should probably point out that this post isn’t a dig at the method that Eric used. He was the only consumer and decided (perfectly validly) that the performance was sufficient. On my machine I decided that it wasn’t (hmm, maybe I need to become more patient!). The key things about this for me are that you need to define your performance goals, measure the performance against those goals and then profile your app to determine where the performance bottlenecks are. Oh, and that LINQ to Objects is pretty powerful – I was able to make this change very easily and with minimal change to the original query.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9460731" width="1" height="1"&gt;</content><author><name>stuartle</name><uri>http://blogs.msdn.com/members/stuartle.aspx</uri></author><category term="LINQ" scheme="http://blogs.msdn.com/stuartleeks/archive/tags/LINQ/default.aspx" /><category term="CSharp" scheme="http://blogs.msdn.com/stuartleeks/archive/tags/CSharp/default.aspx" /></entry><entry><title>Creating database connections with Unity – part 2</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/stuartleeks/archive/2009/01/09/creating-database-connections-with-unity-part-2.aspx" /><id>http://blogs.msdn.com/stuartleeks/archive/2009/01/09/creating-database-connections-with-unity-part-2.aspx</id><published>2009-01-09T16:21:55Z</published><updated>2009-01-09T16:21:55Z</updated><content type="html">&lt;p&gt;&lt;a href="http://blogs.msdn.com/stuartleeks/archive/2009/01/08/creating-database-connections-with-unity.aspx"&gt;Last time&lt;/a&gt; we looked at how to set up the configuration file so that Unity would wire up an object that took an IDbConnection parameter in its constructor. Whilst the solution works, it is easy for the various connection strings to become buried away in the Unity configuration. Also, the application configuration file already has somewhere to put connection details: the &lt;a href="http://msdn.microsoft.com/en-us/library/bf7sd233.aspx"&gt;connectionStrings Element&lt;/a&gt;. This seemed like the ideal place to store my connection strings so I wanted a way to hook this up using Unity. After hunting around the documentation for a while, I noticed that as well as specifying parameters as dependencies (as in the previous post) you can also specify a value. This value has to be entered as a string in the configuration file but you can use the typeConverter attribute to specify the type converter that should be used to turn the string into the appropriate type. At this point the light bulb flicked on and DbConnectionNameTypeConverter entered stage left.&lt;/p&gt;  &lt;p&gt;NOTE: the code below isn’t production ready (and as always, is subject to the standard disclaimer: “These postings are provided &amp;quot;AS IS&amp;quot; with no warranties, and confer no rights. Use of included script samples are subject to the terms specified at &lt;a href="http://www.microsoft.com/info/cpyright.htm"&gt;http://www.microsoft.com/info/cpyright.htm&lt;/a&gt;”).&lt;/p&gt;  &lt;blockquote&gt;   &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;public class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;DbConnectionNameTypeConverter &lt;/span&gt;: &lt;span style="color: #2b91af"&gt;TypeConverter
&lt;/span&gt;{
    &lt;span style="color: blue"&gt;public override object &lt;/span&gt;ConvertFrom(&lt;span style="color: #2b91af"&gt;ITypeDescriptorContext &lt;/span&gt;context, System.Globalization.&lt;span style="color: #2b91af"&gt;CultureInfo &lt;/span&gt;culture, &lt;span style="color: blue"&gt;object &lt;/span&gt;value)
    {
        &lt;span style="color: blue"&gt;string &lt;/span&gt;connectionStringName = (&lt;span style="color: blue"&gt;string&lt;/span&gt;) value;
        &lt;span style="color: #2b91af"&gt;ConnectionStringSettings &lt;/span&gt;connectionStringSettings = &lt;span style="color: #2b91af"&gt;ConfigurationManager&lt;/span&gt;.ConnectionStrings[connectionStringName];

        &lt;span style="color: #2b91af"&gt;DbProviderFactory &lt;/span&gt;providerFactory = &lt;span style="color: #2b91af"&gt;DbProviderFactories&lt;/span&gt;.GetFactory(connectionStringSettings.ProviderName);&lt;span style="color: green"&gt;
        &lt;/span&gt;&lt;span style="color: #2b91af"&gt;IDbConnection &lt;/span&gt;connection = providerFactory.CreateConnection();
        connection.ConnectionString = connectionStringSettings.ConnectionString;
        &lt;span style="color: blue"&gt;return &lt;/span&gt;connection;
    }
}&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;This code simply takes the string passed in and looks up the connection details with that name. It uses the &lt;a href="http://msdn.microsoft.com/en-us/library/system.data.common.dbproviderfactory.aspx"&gt;DbProviderFactory&lt;/a&gt; to create the connection, so it will handle SqlConnection or any other connection type that is registered. With this class in place, we can move the connection configuration to the connectionStrings section:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;connectionStrings&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;add &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;AdventureWorks&lt;/span&gt;&amp;quot;
         &lt;span style="color: red"&gt;connectionString&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;Data Source=(local);Database=AdventureWorks;Integrated Security=SSPI;&lt;/span&gt;&amp;quot;
         &lt;span style="color: red"&gt;providerName&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;System.Data.SqlClient&lt;/span&gt;&amp;quot; &lt;span style="color: blue"&gt;/&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;connectionStrings&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;And then configure Unity to use the type converter to get an IDbConnection instance from the connection name:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;types&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;span style="color: blue"&gt;    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;type &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;MyProject.IRepository, MyProject, Version=1.0.0.0, Culture=neutral&lt;/span&gt;&amp;quot;
          &lt;span style="color: red"&gt;mapTo&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;MyProject.DefaultRepository, MyProject, Version=1.0.0.0, Culture=neutral&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;lifetime &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;transient&lt;/span&gt;&amp;quot; &lt;span style="color: blue"&gt;/&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;typeConfig&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
            &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;constructor&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
                &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;param &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;connection&lt;/span&gt;&amp;quot; &lt;span style="color: red"&gt;parameterType&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;IDbConnection&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;&amp;gt;
                    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;value &lt;/span&gt;&lt;span style="color: red"&gt;value&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;AdventureWorks&lt;/span&gt;&amp;quot; &lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;IDbConnection&lt;/span&gt;&amp;quot; &lt;span style="color: red"&gt;typeConverter&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;DbConnectionNameTypeConverter&lt;/span&gt;&amp;quot; &lt;span style="color: blue"&gt;/&amp;gt;
                &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;param&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
            &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;constructor&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
        &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;typeConfig&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;types&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;And bingo! We get all of the Unity goodness from the previous post but reuse the existing configuration section to centralise the connection settings!&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9301919" width="1" height="1"&gt;</content><author><name>stuartle</name><uri>http://blogs.msdn.com/members/stuartle.aspx</uri></author><category term="CSharp" scheme="http://blogs.msdn.com/stuartleeks/archive/tags/CSharp/default.aspx" /><category term="Unity" scheme="http://blogs.msdn.com/stuartleeks/archive/tags/Unity/default.aspx" /></entry><entry><title>Creating database connections with Unity</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/stuartleeks/archive/2009/01/08/creating-database-connections-with-unity.aspx" /><id>http://blogs.msdn.com/stuartleeks/archive/2009/01/08/creating-database-connections-with-unity.aspx</id><published>2009-01-09T01:09:33Z</published><updated>2009-01-09T01:09:33Z</updated><content type="html">&lt;p&gt;I was adding dependency injection to an existing project and opted to use &lt;a href="http://msdn.microsoft.com/en-us/library/dd203101.aspx"&gt;Unity&lt;/a&gt; configured via the application configuration file. As I was running through the configuration, I hit a type that required a&amp;#160; database connection which it took in as an &lt;a href="http://msdn.microsoft.com/en-us/library/system.data.idbconnection.aspx"&gt;IDbConnection&lt;/a&gt; reference in the constructor so I added the following config under the container element:&lt;/p&gt;  &lt;blockquote&gt;   &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;types&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;type &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;MyProject.IRepository, MyProject, Version=1.0.0.0, Culture=neutral&lt;/span&gt;&amp;quot;
          &lt;span style="color: red"&gt;mapTo&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;MyProject.DefaultRepository, MyProject, Version=1.0.0.0, Culture=neutral&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;lifetime &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;transient&lt;/span&gt;&amp;quot; &lt;span style="color: blue"&gt;/&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;typeConfig&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
            &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;constructor&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
                &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;param &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;connection&lt;/span&gt;&amp;quot; &lt;span style="color: red"&gt;parameterType&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;IDbConnection&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;&amp;gt;
                    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;dependency &lt;/span&gt;&lt;span style="color: blue"&gt;/&amp;gt;
                &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;param&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
            &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;constructor&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
        &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;typeConfig&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: blue"&gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;types&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;(Before going any further, I should point out that I’ve added a &lt;a href="http://msdn.microsoft.com/en-us/library/cc440942.aspx#config_typealiases"&gt;type alias&lt;/a&gt; to the config for IDbConnection to save entering “System.Data.IDbConnection, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089” each time.)&lt;/p&gt;

&lt;p&gt;If you’re not familiar with the configuration file options for Unity, each type element tells Unity what to do when that type is requested. In the case of IRepository the mapTo attribute instructs Unity to create an instance of DefaultRepository. The typeConfig section is used to specify how you want Unity to create the type and in this case we are instructing it to use the constructor that takes a single parameter of type IDbConnection. The dependency sub-element tells Unity to use itself to resolve the value for the IDbConnection parameter, so we need to add that to the config:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;types&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;type &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;MyProject.IRepository, MyProject, Version=1.0.0.0, Culture=neutral&lt;/span&gt;&amp;quot;
          &lt;span style="color: red"&gt;mapTo&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;MyProject.DefaultRepository, MyProject, Version=1.0.0.0, Culture=neutral&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;lifetime &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;transient&lt;/span&gt;&amp;quot; &lt;span style="color: blue"&gt;/&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;typeConfig&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
            &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;constructor&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
                &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;param &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;connection&lt;/span&gt;&amp;quot; &lt;span style="color: red"&gt;parameterType&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;IDbConnection&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;&amp;gt;
                    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;dependency &lt;/span&gt;&lt;span style="color: blue"&gt;/&amp;gt;
                &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;param&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
            &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;constructor&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
        &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;typeConfig&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;type &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;IDbConnection&lt;/span&gt;&amp;quot; 
          &lt;span style="color: red"&gt;mapTo&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;SqlConnection&lt;/span&gt;&amp;quot; &lt;span style="color: blue"&gt;&amp;gt;
        &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;typeConfig&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
            &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;constructor&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
                &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;param &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;connectionString&lt;/span&gt;&amp;quot; &lt;span style="color: red"&gt;parameterType&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;System.String&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;&amp;gt;
                    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;value &lt;/span&gt;&lt;span style="color: red"&gt;value&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;Data Source=(local);Database=AdventureWorks;Integrated Security=SSPI;&lt;/span&gt;&amp;quot; &lt;span style="color: blue"&gt;/&amp;gt;
                &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;param&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
            &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;constructor&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
        &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;typeConfig&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;types&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;We’ve now given Unity enough information to resolve the IRepository type and wire up the IDbConnection parameter in the constructor. One problem with this config is that whenever we try to resolve an IDbConnection we’re going to get a connection to AdventureWorks and my application needs a couple of different database connections. Fortunately Unity provides for this situation and we can add a name to the type mapping. So the IDbConnection specification becomes:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;type &lt;/span&gt;&lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;IDbConnection&lt;/span&gt;&amp;quot; 
          &lt;span style="color: red"&gt;mapTo&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;SqlConnection&lt;/span&gt;&amp;quot; 
&lt;strong&gt;&lt;em&gt;          &lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;AdventureWorksConnection&lt;/span&gt;&amp;quot;&lt;/em&gt;&lt;/strong&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;and we can now refer to this type by name in the parameter dependency:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;dependency &lt;/span&gt;&lt;strong&gt;&lt;em&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;AdventureWorksConnection&lt;/span&gt;&amp;quot;&lt;/em&gt;&lt;/strong&gt; &lt;span style="color: blue"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;This allows us to define multiple connection entries that we simply refer to by name when we need to. Using this approach, the same connection details can be referenced in multiple places in the config so connecting to a different server or database is simply a case of changing the connection string in a single place.&amp;#160; Also, assuming our repository class is able to deal with multiple database providers we can simply switch out the provider by changing the type Unity is creating for us (currently SqlConnection). &lt;/p&gt;

&lt;p&gt;There’s lots more to Unity and for more information the &lt;a href="http://msdn.microsoft.com/en-us/library/cc440954.aspx"&gt;Introduction to Unity&lt;/a&gt; page on MSDN is a good place to start. Next time we’ll take advantage of some of the flexibility of Unity to fix an something that I don’t really like about the above solution.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9300567" width="1" height="1"&gt;</content><author><name>stuartle</name><uri>http://blogs.msdn.com/members/stuartle.aspx</uri></author><category term="CSharp" scheme="http://blogs.msdn.com/stuartleeks/archive/tags/CSharp/default.aspx" /><category term="Unity" scheme="http://blogs.msdn.com/stuartleeks/archive/tags/Unity/default.aspx" /></entry><entry><title>Microsoft AutoCollage 2008</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/stuartleeks/archive/2008/09/15/microsoft-autocollage-2008.aspx" /><id>http://blogs.msdn.com/stuartleeks/archive/2008/09/15/microsoft-autocollage-2008.aspx</id><published>2008-09-15T11:27:56Z</published><updated>2008-09-15T11:27:56Z</updated><content type="html">&lt;p&gt;I just thought I’d mention that Microsoft AutoCollage 2008 has been released. It is based on research from Microsoft Research in Cambridge and allows you to automatically create collages of images (not that you’d have guessed it from the name ;-) ). You can find out more, see example images, and download a free 30-day trial version from &lt;a href="http://research.microsoft.com/AutoCollage"&gt;http://research.microsoft.com/AutoCollage&lt;/a&gt; (you can follow the download links to purchase it at the Microsoft online store). There are lots of great examples on the AutoCollage page, but I thought I’d add a personal collage…&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.stuart.leeks.members.winisp.net/blogimages/MicrosoftAutoCollage2008_D7CE/2_AutoCollage_11_Images_2.jpg"&gt;&lt;img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="2_AutoCollage_11_Images_2" border="0" alt="2_AutoCollage_11_Images_2" src="http://www.stuart.leeks.members.winisp.net/blogimages/MicrosoftAutoCollage2008_D7CE/2_AutoCollage_11_Images_2_thumb.jpg" width="244" height="196" /&gt;&lt;/a&gt; (click to enlarge)&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;In case you’re wondering, the collage is of James&amp;#160; - the recent arrival to the Leeks clan :-D&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8952217" width="1" height="1"&gt;</content><author><name>stuartle</name><uri>http://blogs.msdn.com/members/stuartle.aspx</uri></author></entry><entry><title>DataServiceQuery&lt;T&gt;.Expand</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/stuartleeks/archive/2008/09/15/dataservicequery-t-expand.aspx" /><id>http://blogs.msdn.com/stuartleeks/archive/2008/09/15/dataservicequery-t-expand.aspx</id><published>2008-09-15T11:25:00Z</published><updated>2008-09-15T11:25:00Z</updated><content type="html">&lt;P&gt;&lt;A href="http://msdn.microsoft.com/en-us/data/bb931106.aspx" mce_href="http://msdn.microsoft.com/en-us/data/bb931106.aspx"&gt;ADO.Net Data Services&lt;/A&gt; allows you to expose your &lt;A href="http://msdn.microsoft.com/en-us/library/bb386964.aspx" mce_href="http://msdn.microsoft.com/en-us/library/bb386964.aspx"&gt;LINQ To Entities&lt;/A&gt; model (or &lt;A href="http://msdn.microsoft.com/en-us/library/bb386976.aspx" mce_href="http://msdn.microsoft.com/en-us/library/bb386976.aspx"&gt;LINQ To SQL&lt;/A&gt; model, or even your custom &lt;A href="http://msdn.microsoft.com/en-us/library/bb351562.aspx" mce_href="http://msdn.microsoft.com/en-us/library/bb351562.aspx"&gt;IQueryable&lt;/A&gt; model) via a &lt;A href="http://en.wikipedia.org/wiki/REST" mce_href="http://en.wikipedia.org/wiki/REST"&gt;REST&lt;/A&gt;ful API with minimal coding. For example, if you’re working with the Northwind database you can use the URL http://server/Service.svc/Customers(‘ALFKI’)/Orders to retrieve the orders for customer ALFKI. This simplicity makes it easy to retrieve data in a variety of scenarios – you simply need to be able to issue HTTP requests to access the data. To make it really easy to consume the data from client-side javascript, you can even specify that you want the data to be in &lt;A href="http://msdn.microsoft.com/en-us/library/bb299886.aspx" mce_href="http://msdn.microsoft.com/en-us/library/bb299886.aspx"&gt;JSON&lt;/A&gt; format. In rich client scenarios, you can either work with HTTP requests or if you like to make things really easy you can create a LINQ data model to access your ADO.Net Data Service. Simply point DataSvcUtil at your service and it will generate the LINQ classes you need. There’s a very good article by Shawn Wildermuth in the September 2008 issue of MSDN Magazine called ‘Creating Data-Centric Web Applications With Silverlight 2’ [1] that takes you through the process of creating a service and the LINQ classes to access the service from Silverlight. The article also discusses the mechanisms that ADO.Net Data Services uses to discover your entities if you want to expose your custom model (or if you’re just interested in how it works). I’ve also included a few extra links in the references at the end of the post if you want to find out more. Now, back to the point of the post...&lt;/P&gt;
&lt;P&gt;The client-side code can use the &lt;A href="http://msdn.microsoft.com/en-us/library/cc679728.aspx" mce_href="http://msdn.microsoft.com/en-us/library/cc679728.aspx"&gt;DataServiceQuery&amp;lt;T&amp;gt;.Expand&lt;/A&gt; method to specify what properties should also be retrieved (much like the Include method in my last post &lt;A href="http://blogs.msdn.com/stuartleeks/archive/2008/08/27/improving-objectquery-t-include.aspx" mce_href="http://blogs.msdn.com/stuartleeks/archive/2008/08/27/improving-objectquery-t-include.aspx"&gt;Improving ObjectQuery&amp;lt;T&amp;gt;.Include&lt;/A&gt;). So you can write the following query to retrieve the customer ALFKI from the Northwind database and also pull back the orders:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;var &lt;/SPAN&gt;q = &lt;SPAN style="COLOR: blue"&gt;from &lt;/SPAN&gt;c &lt;SPAN style="COLOR: blue"&gt;in &lt;/SPAN&gt;context.Customers.Expand(&lt;SPAN style="COLOR: #a31515"&gt;"Orders/Order_Details"&lt;/SPAN&gt;)
        &lt;SPAN style="COLOR: blue"&gt;where &lt;/SPAN&gt;c.CustomerID == &lt;SPAN style="COLOR: #a31515"&gt;"ALFKI"
        &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;select &lt;/SPAN&gt;c;&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P&gt;Notice the call to the Expand Method. Much like the Include method for &lt;A href="http://msdn.microsoft.com/en-us/library/bb386964.aspx" mce_href="http://msdn.microsoft.com/en-us/library/bb386964.aspx"&gt;LINQ To Entities&lt;/A&gt; (see &lt;A href="http://blogs.msdn.com/stuartleeks/archive/2008/08/27/improving-objectquery-t-include.aspx" mce_href="http://blogs.msdn.com/stuartleeks/archive/2008/08/27/improving-objectquery-t-include.aspx"&gt;my last post&lt;/A&gt;), this lets yoe specify that you want certain related data to be pre-fetched. If you wanted to get the order details included as well then you could change the query to:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;var &lt;/SPAN&gt;q = &lt;SPAN style="COLOR: blue"&gt;from &lt;/SPAN&gt;c &lt;SPAN style="COLOR: blue"&gt;in &lt;/SPAN&gt;context.Customers.Expand(&lt;SPAN style="COLOR: #a31515"&gt;"&lt;STRONG&gt;Orders/Order_Details&lt;/STRONG&gt;"&lt;/SPAN&gt;)
        &lt;SPAN style="COLOR: blue"&gt;where &lt;/SPAN&gt;c.CustomerID == &lt;SPAN style="COLOR: #a31515"&gt;"ALFKI"
        &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;select &lt;/SPAN&gt;c;&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;One point to notice is that it uses a forward slash (‘/’) rather than a decimal (‘.’) as the path separator, other than that it’s pretty similar to Include. Applying the same logic as in &lt;A href="http://blogs.msdn.com/stuartleeks/archive/2008/08/27/improving-objectquery-t-include.aspx" mce_href="http://blogs.msdn.com/stuartleeks/archive/2008/08/27/improving-objectquery-t-include.aspx"&gt;my last post&lt;/A&gt;, we can quickly create &lt;A href="http://msdn.microsoft.com/en-us/library/bb383977.aspx" mce_href="http://msdn.microsoft.com/en-us/library/bb383977.aspx"&gt;extension methods&lt;/A&gt; that allow us to write the above queries as &lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;var &lt;/SPAN&gt;q = &lt;SPAN style="COLOR: blue"&gt;from &lt;/SPAN&gt;c &lt;SPAN style="COLOR: blue"&gt;in &lt;/SPAN&gt;context.Customers.Expand(c =&amp;gt; c.Orders)
        &lt;SPAN style="COLOR: blue"&gt;where &lt;/SPAN&gt;c.CustomerID == &lt;SPAN style="COLOR: #a31515"&gt;"ALFKI"
        &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;select &lt;/SPAN&gt;c;&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P&gt;and &lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;var &lt;/SPAN&gt;q = &lt;SPAN style="COLOR: blue"&gt;from &lt;/SPAN&gt;c &lt;SPAN style="COLOR: blue"&gt;in &lt;/SPAN&gt;context.Customers.Expand(c =&amp;gt; c.Orders.SubExpand(o=&amp;gt; o.Order_Details))
        &lt;SPAN style="COLOR: blue"&gt;where &lt;/SPAN&gt;c.CustomerID == &lt;SPAN style="COLOR: #a31515"&gt;"ALFKI"
        &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;select &lt;/SPAN&gt;c;&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Note that you can also expand multiple properties on the same entity. So if you were querying for orders, you can also bring back the customer and order details:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;var &lt;/SPAN&gt;q = &lt;SPAN style="COLOR: blue"&gt;from &lt;/SPAN&gt;o &lt;SPAN style="COLOR: blue"&gt;in &lt;/SPAN&gt;context.Orders.Expand(o=&amp;gt;o.Customer).Expand(o=&amp;gt;o.Order_Details)
        &lt;SPAN style="COLOR: blue"&gt;where &lt;/SPAN&gt;o.Customer.CustomerID == &lt;SPAN style="COLOR: #a31515"&gt;"ALFKI"
        &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;select &lt;/SPAN&gt;o;&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P&gt;The code for the &lt;A href="http://msdn.microsoft.com/en-us/library/bb383977.aspx" mce_href="http://msdn.microsoft.com/en-us/library/bb383977.aspx"&gt;extension method&lt;/A&gt; is shown below – note that the code isn’t production ready (and as always, is subject to the standard disclaimer: “These postings are provided "AS IS" with no warranties, and confer no rights. Use of included script samples are subject to the terms specified at &lt;A href="http://www.microsoft.com/info/cpyright.htm" mce_href="http://www.microsoft.com/info/cpyright.htm"&gt;http://www.microsoft.com/info/cpyright.htm&lt;/A&gt;”). Since this code is very similar to my &lt;A href="http://blogs.msdn.com/stuartleeks/archive/2008/08/27/improving-objectquery-t-include.aspx" mce_href="http://blogs.msdn.com/stuartleeks/archive/2008/08/27/improving-objectquery-t-include.aspx"&gt;previous post&lt;/A&gt;, and gives you the same benefits, I’ll refer you to &lt;A href="http://blogs.msdn.com/stuartleeks/archive/2008/08/27/improving-objectquery-t-include.aspx" mce_href="http://blogs.msdn.com/stuartleeks/archive/2008/08/27/improving-objectquery-t-include.aspx"&gt;that post&lt;/A&gt; if you want to know how the code works and what the benefits are!&lt;/P&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;public static class &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;DataServiceQueryExtensions
&lt;/SPAN&gt;{
    &lt;SPAN style="COLOR: blue"&gt;public static &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;DataServiceQuery&lt;/SPAN&gt;&amp;lt;TSource&amp;gt; Expand&amp;lt;TSource, TPropType&amp;gt;(&lt;SPAN style="COLOR: blue"&gt;this &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;DataServiceQuery&lt;/SPAN&gt;&amp;lt;TSource&amp;gt; source, &lt;SPAN style="COLOR: #2b91af"&gt;Expression&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: #2b91af"&gt;Func&lt;/SPAN&gt;&amp;lt;TSource, TPropType&amp;gt;&amp;gt; propertySelector)
    {
        &lt;SPAN style="COLOR: blue"&gt;string &lt;/SPAN&gt;expandString = BuildString(propertySelector);
        &lt;SPAN style="COLOR: blue"&gt;return &lt;/SPAN&gt;source.Expand(expandString);
    }
    &lt;SPAN style="COLOR: blue"&gt;private static string &lt;/SPAN&gt;BuildString(&lt;SPAN style="COLOR: #2b91af"&gt;Expression &lt;/SPAN&gt;propertySelector)
    {
        &lt;SPAN style="COLOR: blue"&gt;switch &lt;/SPAN&gt;(propertySelector.NodeType)
        {
            &lt;SPAN style="COLOR: blue"&gt;case &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;ExpressionType&lt;/SPAN&gt;.Lambda:
                &lt;SPAN style="COLOR: #2b91af"&gt;LambdaExpression &lt;/SPAN&gt;lambdaExpression = (&lt;SPAN style="COLOR: #2b91af"&gt;LambdaExpression&lt;/SPAN&gt;)propertySelector;
                &lt;SPAN style="COLOR: blue"&gt;return &lt;/SPAN&gt;BuildString(lambdaExpression.Body);

            &lt;SPAN style="COLOR: blue"&gt;case &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;ExpressionType&lt;/SPAN&gt;.Quote:
                &lt;SPAN style="COLOR: #2b91af"&gt;UnaryExpression &lt;/SPAN&gt;unaryExpression = (&lt;SPAN style="COLOR: #2b91af"&gt;UnaryExpression&lt;/SPAN&gt;)propertySelector;
                &lt;SPAN style="COLOR: blue"&gt;return &lt;/SPAN&gt;BuildString(unaryExpression.Operand);

            &lt;SPAN style="COLOR: blue"&gt;case &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;ExpressionType&lt;/SPAN&gt;.MemberAccess:
                &lt;SPAN style="COLOR: #2b91af"&gt;MemberInfo &lt;/SPAN&gt;propertyInfo = ((&lt;SPAN style="COLOR: #2b91af"&gt;MemberExpression&lt;/SPAN&gt;)propertySelector).Member;
                &lt;SPAN style="COLOR: blue"&gt;return &lt;/SPAN&gt;propertyInfo.Name;

            &lt;SPAN style="COLOR: blue"&gt;case &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;ExpressionType&lt;/SPAN&gt;.Call:
                &lt;SPAN style="COLOR: #2b91af"&gt;MethodCallExpression &lt;/SPAN&gt;methodCallExpression = (&lt;SPAN style="COLOR: #2b91af"&gt;MethodCallExpression&lt;/SPAN&gt;)propertySelector;
                &lt;SPAN style="COLOR: blue"&gt;if &lt;/SPAN&gt;(IsSubExpand(methodCallExpression.Method)) &lt;SPAN style="COLOR: green"&gt;// check that it's a SubExpand call
                &lt;/SPAN&gt;{
                    &lt;SPAN style="COLOR: green"&gt;// argument 0 is the expression to which the SubExpand is applied (this could be member access or another SubExpand)
                    // argument 1 is the expression to apply to get the expanded property
                    // Pass both to BuildString to get the full expression
                    &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;return &lt;/SPAN&gt;BuildString(methodCallExpression.Arguments[0]) + &lt;SPAN style="COLOR: #a31515"&gt;"/" &lt;/SPAN&gt;+
                           BuildString(methodCallExpression.Arguments[1]);
                }
                &lt;SPAN style="COLOR: green"&gt;// else drop out and throw
                &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;break&lt;/SPAN&gt;;
        }
        &lt;SPAN style="COLOR: blue"&gt;throw new &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;InvalidOperationException&lt;/SPAN&gt;(&lt;SPAN style="COLOR: #a31515"&gt;"Expression must be a member expression or an SubExpand call: " &lt;/SPAN&gt;+ propertySelector.ToString());

    }

    &lt;SPAN style="COLOR: blue"&gt;private static readonly &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;MethodInfo&lt;/SPAN&gt;[] SubExpandMethods;
    &lt;SPAN style="COLOR: blue"&gt;static &lt;/SPAN&gt;DataServiceQueryExtensions()
    {
        &lt;SPAN style="COLOR: #2b91af"&gt;Type &lt;/SPAN&gt;type = &lt;SPAN style="COLOR: blue"&gt;typeof&lt;/SPAN&gt;(&lt;SPAN style="COLOR: #2b91af"&gt;DataServiceQueryExtensions&lt;/SPAN&gt;);
        SubExpandMethods = type.GetMethods().Where(mi =&amp;gt; mi.Name == &lt;SPAN style="COLOR: #a31515"&gt;"SubExpand"&lt;/SPAN&gt;).ToArray();
    }
    &lt;SPAN style="COLOR: blue"&gt;private static bool &lt;/SPAN&gt;IsSubExpand(&lt;SPAN style="COLOR: #2b91af"&gt;MethodInfo &lt;/SPAN&gt;methodInfo)
    {
        &lt;SPAN style="COLOR: blue"&gt;if &lt;/SPAN&gt;(methodInfo.IsGenericMethod)
        {
            &lt;SPAN style="COLOR: blue"&gt;if &lt;/SPAN&gt;(!methodInfo.IsGenericMethodDefinition)
            {
                methodInfo = methodInfo.GetGenericMethodDefinition();
            }
        }
        &lt;SPAN style="COLOR: blue"&gt;return &lt;/SPAN&gt;SubExpandMethods.Contains(methodInfo);
    }

    &lt;SPAN style="COLOR: blue"&gt;public static &lt;/SPAN&gt;TPropType SubExpand&amp;lt;TSource, TPropType&amp;gt;(&lt;SPAN style="COLOR: blue"&gt;this &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Collection&lt;/SPAN&gt;&amp;lt;TSource&amp;gt; source, &lt;SPAN style="COLOR: #2b91af"&gt;Expression&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: #2b91af"&gt;Func&lt;/SPAN&gt;&amp;lt;TSource, TPropType&amp;gt;&amp;gt; propertySelector)
        &lt;SPAN style="COLOR: blue"&gt;where &lt;/SPAN&gt;TSource : &lt;SPAN style="COLOR: blue"&gt;class
        where &lt;/SPAN&gt;TPropType : &lt;SPAN style="COLOR: blue"&gt;class
    &lt;/SPAN&gt;{
        &lt;SPAN style="COLOR: blue"&gt;throw new &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;InvalidOperationException&lt;/SPAN&gt;(&lt;SPAN style="COLOR: #a31515"&gt;"This method is only intended for use with DataServiceQueryExtensions.Expand to generate expressions trees"&lt;/SPAN&gt;); &lt;SPAN style="COLOR: green"&gt;// no actually using this - just want the expression!
    &lt;/SPAN&gt;}
    &lt;SPAN style="COLOR: blue"&gt;public static &lt;/SPAN&gt;TPropType SubExpand&amp;lt;TSource, TPropType&amp;gt;(&lt;SPAN style="COLOR: blue"&gt;this &lt;/SPAN&gt;TSource source, &lt;SPAN style="COLOR: #2b91af"&gt;Expression&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: #2b91af"&gt;Func&lt;/SPAN&gt;&amp;lt;TSource, TPropType&amp;gt;&amp;gt; propertySelector)
        &lt;SPAN style="COLOR: blue"&gt;where &lt;/SPAN&gt;TSource : &lt;SPAN style="COLOR: blue"&gt;class
        where &lt;/SPAN&gt;TPropType : &lt;SPAN style="COLOR: blue"&gt;class
    &lt;/SPAN&gt;{
        &lt;SPAN style="COLOR: blue"&gt;throw new &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;InvalidOperationException&lt;/SPAN&gt;(&lt;SPAN style="COLOR: #a31515"&gt;"This method is only intended for use with DataServiceQueryExtensions.Expand to generate expressions trees"&lt;/SPAN&gt;); &lt;SPAN style="COLOR: green"&gt;// no actually using this - just want the expression!
    &lt;/SPAN&gt;}
}&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P mce_keep="true"&gt;References:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;1: Creating Data-Centric Web Applications With Silverlight 2, Shawn Wildermuth. MSDN Magazine, September 2008. &lt;A title=http://msdn.microsoft.com/en-us/magazine/cc794279.aspx href="http://msdn.microsoft.com/en-us/magazine/cc794279.aspx" mce_href="http://msdn.microsoft.com/en-us/magazine/cc794279.aspx"&gt;http://msdn.microsoft.com/en-us/magazine/cc794279.aspx&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;2 ADO.Net Data Services team blog. &lt;A title=http://blogs.msdn.com/astoriateam/ href="http://blogs.msdn.com/astoriateam/" mce_href="http://blogs.msdn.com/astoriateam/"&gt;http://blogs.msdn.com/astoriateam/&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;3 ADO.Net Data Services homepage on MSDN. &lt;A title=http://msdn.microsoft.com/en-us/data/bb931106.aspx href="http://msdn.microsoft.com/en-us/data/bb931106.aspx" mce_href="http://msdn.microsoft.com/en-us/data/bb931106.aspx"&gt;http://msdn.microsoft.com/en-us/data/bb931106.aspx&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;4 Mike Taulty has a number of blog posts on ADO.Net Data Services. &lt;A title=http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/category/1027.aspx href="http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/category/1027.aspx" mce_href="http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/category/1027.aspx"&gt;http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/category/1027.aspx&lt;/A&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8952213" width="1" height="1"&gt;</content><author><name>stuartle</name><uri>http://blogs.msdn.com/members/stuartle.aspx</uri></author><category term="LINQ" scheme="http://blogs.msdn.com/stuartleeks/archive/tags/LINQ/default.aspx" /><category term="CSharp" scheme="http://blogs.msdn.com/stuartleeks/archive/tags/CSharp/default.aspx" /><category term="Extension methods" scheme="http://blogs.msdn.com/stuartleeks/archive/tags/Extension+methods/default.aspx" /><category term="ADO.Net Data Services" scheme="http://blogs.msdn.com/stuartleeks/archive/tags/ADO.Net+Data+Services/default.aspx" /></entry><entry><title>Improving ObjectQuery&lt;T&gt;.Include</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/stuartleeks/archive/2008/08/27/improving-objectquery-t-include.aspx" /><id>http://blogs.msdn.com/stuartleeks/archive/2008/08/27/improving-objectquery-t-include.aspx</id><published>2008-08-28T01:35:00Z</published><updated>2008-08-28T01:35:00Z</updated><content type="html">&lt;H2&gt;** UPDATE: There’s a bug in the code below – see &lt;A href="http://blogs.msdn.com/stuartleeks/archive/2009/04/24/improving-objectquery-t-include-updated.aspx"&gt;this post&lt;/A&gt; for the update!&lt;/H2&gt;
&lt;P&gt;One of the great features of &lt;A href="http://msdn.microsoft.com/en-us/library/bb386976.aspx" mce_href="http://msdn.microsoft.com/en-us/library/bb386976.aspx"&gt;LINQ To SQL&lt;/A&gt; and &lt;A href="http://msdn.microsoft.com/en-us/library/bb386964.aspx" mce_href="http://msdn.microsoft.com/en-us/library/bb386964.aspx"&gt;LINQ To Entities&lt;/A&gt; is that the queries you write are checked by the compiler, which eliminates typing errors in your query. Unfortunately, the &lt;A href="http://msdn.microsoft.com/en-us/library/bb738708.aspx" mce_href="http://msdn.microsoft.com/en-us/library/bb738708.aspx"&gt;ObjectQuery&amp;lt;T&amp;gt;.Include&lt;/A&gt; function (which is used to eager-load data that isn’t directly included in the query) takes a string parameter, opening up opportunities for typos to creep back in. In this post I’ll present some sample code that illustrates one way that you can work round this. To start with, let’s take a quick look at a query against an entity model on the Northwind database.&lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;var &lt;/SPAN&gt;query = &lt;SPAN style="COLOR: blue"&gt;from &lt;/SPAN&gt;customer &lt;SPAN style="COLOR: blue"&gt;in &lt;/SPAN&gt;context.Customers
&lt;SPAN style="COLOR: blue"&gt;            where &lt;/SPAN&gt;customer.Orders.Count &amp;gt; 0
            &lt;SPAN style="COLOR: blue"&gt;select &lt;/SPAN&gt;customer;&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;This query simply retrieves customers with an order. If the code that uses the query results then needs to make use of the order data, it won’t have been loaded. We can use the Include function to ensure that this data is loaded up front:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;var &lt;/SPAN&gt;query = &lt;SPAN style="COLOR: blue"&gt;from &lt;/SPAN&gt;customer &lt;SPAN style="COLOR: blue"&gt;in &lt;/SPAN&gt;context.Customers&lt;STRONG&gt;.Include(&lt;SPAN style="COLOR: #a31515"&gt;"Orders"&lt;/SPAN&gt;)&lt;/STRONG&gt;
&lt;SPAN style="COLOR: blue"&gt;            where &lt;/SPAN&gt;customer.Orders.Count &amp;gt; 0
            &lt;SPAN style="COLOR: blue"&gt;select &lt;/SPAN&gt;customer;&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P&gt;Notice the Include(“Orders”) call that we’ve inserted which instructs Entity Framework to retrieve the Orders for each Customer. It would be much nicer if we could use a lambda expression to specify what property to load:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;var &lt;/SPAN&gt;query = &lt;SPAN style="COLOR: blue"&gt;from &lt;/SPAN&gt;customer &lt;SPAN style="COLOR: blue"&gt;in &lt;/SPAN&gt;context.Customers.Include(c =&amp;gt; c.Orders)
            &lt;SPAN style="COLOR: blue"&gt;where &lt;/SPAN&gt;customer.Orders.Count &amp;gt; 0
            &lt;SPAN style="COLOR: blue"&gt;select &lt;/SPAN&gt;customer;&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P&gt;It turns out that this is very easy to achieve by using an &lt;A href="http://msdn.microsoft.com/en-us/library/bb383977.aspx" mce_href="http://msdn.microsoft.com/en-us/library/bb383977.aspx"&gt;extension method&lt;/A&gt;:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;public static class &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;ObjectQueryExtensions
&lt;/SPAN&gt;{
    &lt;SPAN style="COLOR: blue"&gt;public static &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;ObjectQuery&lt;/SPAN&gt;&amp;lt;TSource&amp;gt; Include&amp;lt;TSource, TPropType&amp;gt;(&lt;SPAN style="COLOR: blue"&gt;this &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;ObjectQuery&lt;/SPAN&gt;&amp;lt;TSource&amp;gt; source, &lt;SPAN style="COLOR: #2b91af"&gt;Expression&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: #2b91af"&gt;Func&lt;/SPAN&gt;&amp;lt;TSource, TPropType&amp;gt;&amp;gt; propertySelector)
    {
        &lt;SPAN style="COLOR: #2b91af"&gt;MemberExpression &lt;/SPAN&gt;memberExpression = propertySelector.Body &lt;SPAN style="COLOR: blue"&gt;as &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;MemberExpression&lt;/SPAN&gt;;
        &lt;SPAN style="COLOR: blue"&gt;if &lt;/SPAN&gt;(memberExpression== &lt;SPAN style="COLOR: blue"&gt;null&lt;/SPAN&gt;)
        {
            &lt;SPAN style="COLOR: blue"&gt;throw new &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;InvalidOperationException&lt;/SPAN&gt;(&lt;SPAN style="COLOR: #a31515"&gt;"Expression must be a member expression" &lt;/SPAN&gt;+ propertySelector);
        }
        &lt;SPAN style="COLOR: #2b91af"&gt;MemberInfo &lt;/SPAN&gt;propertyInfo = memberExpression.Member;
        &lt;SPAN style="COLOR: blue"&gt;return &lt;/SPAN&gt;source.Include(propertyInfo.Name);
    }
}&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P&gt;This Include extension method allows the query syntax above with the lambda expression. When the Include method is called, it inspects the &lt;A href="http://msdn.microsoft.com/en-us/library/bb397951.aspx" mce_href="http://msdn.microsoft.com/en-us/library/bb397951.aspx"&gt;Expression Tree&lt;/A&gt;. If the method is used as intended, the tree will describe a accessing a member of the TSource class. We can then us the name of the member to call the original Include function.&lt;/P&gt;
&lt;P&gt;Whilst this solves the problem as I described it above, what if the code consuming the query also needed the order details? With the original Include function we can write &lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;var &lt;/SPAN&gt;query = &lt;SPAN style="COLOR: blue"&gt;from &lt;/SPAN&gt;customer &lt;SPAN style="COLOR: blue"&gt;in &lt;/SPAN&gt;context.Customers&lt;STRONG&gt;.Include(&lt;SPAN style="COLOR: #a31515"&gt;"Orders.Order_Details"&lt;/SPAN&gt;)&lt;/STRONG&gt; 
&lt;SPAN style="COLOR: blue"&gt;            where &lt;/SPAN&gt;customer.Orders.Count &amp;gt; 0
            &lt;SPAN style="COLOR: blue"&gt;select &lt;/SPAN&gt;customer;&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Notice that we can pass a path to the properties to include. The extension method we wrote doesn’t give us a way to handle this case. I imagine using something like the syntax below to describe this situation&lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;var &lt;/SPAN&gt;query = &lt;SPAN style="COLOR: blue"&gt;from &lt;/SPAN&gt;customer &lt;SPAN style="COLOR: blue"&gt;in &lt;/SPAN&gt;context.Customers.Include(c =&amp;gt; c.Orders.SubInclude(o =&amp;gt; o.Order_Details))
            &lt;SPAN style="COLOR: blue"&gt;where &lt;/SPAN&gt;customer.Orders.Count &amp;gt; 0
            &lt;SPAN style="COLOR: blue"&gt;select &lt;/SPAN&gt;customer;&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P&gt;Here, we’ve specified that we want to include Orders, and then also that we want to include Order_Details. Adding this support is a bit more code, but not too bad:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;public static class &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;ObjectQueryExtensions
&lt;/SPAN&gt;{
    &lt;SPAN style="COLOR: blue"&gt;public static &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;ObjectQuery&lt;/SPAN&gt;&amp;lt;TSource&amp;gt; Include&amp;lt;TSource, TPropType&amp;gt;(&lt;SPAN style="COLOR: blue"&gt;this &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;ObjectQuery&lt;/SPAN&gt;&amp;lt;TSource&amp;gt; source, &lt;SPAN style="COLOR: #2b91af"&gt;Expression&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: #2b91af"&gt;Func&lt;/SPAN&gt;&amp;lt;TSource, TPropType&amp;gt;&amp;gt; propertySelector)
    {
        &lt;SPAN style="COLOR: blue"&gt;string &lt;/SPAN&gt;includeString = BuildString(propertySelector);
        &lt;SPAN style="COLOR: blue"&gt;return &lt;/SPAN&gt;source.Include(includeString);
    }
    &lt;SPAN style="COLOR: blue"&gt;private static string &lt;/SPAN&gt;BuildString(&lt;SPAN style="COLOR: #2b91af"&gt;Expression &lt;/SPAN&gt;propertySelector)
    {
        &lt;SPAN style="COLOR: blue"&gt;switch&lt;/SPAN&gt;(propertySelector.NodeType)
        {
            &lt;SPAN style="COLOR: blue"&gt;case &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;ExpressionType&lt;/SPAN&gt;.Lambda:
                &lt;SPAN style="COLOR: #2b91af"&gt;LambdaExpression &lt;/SPAN&gt;lambdaExpression = (&lt;SPAN style="COLOR: #2b91af"&gt;LambdaExpression&lt;/SPAN&gt;)propertySelector;
                &lt;SPAN style="COLOR: blue"&gt;return &lt;/SPAN&gt;BuildString(lambdaExpression.Body);

            &lt;SPAN style="COLOR: blue"&gt;case &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;ExpressionType&lt;/SPAN&gt;.Quote:
                &lt;SPAN style="COLOR: #2b91af"&gt;UnaryExpression &lt;/SPAN&gt;unaryExpression= (&lt;SPAN style="COLOR: #2b91af"&gt;UnaryExpression&lt;/SPAN&gt;)propertySelector;
                &lt;SPAN style="COLOR: blue"&gt;return &lt;/SPAN&gt;BuildString(unaryExpression.Operand);

            &lt;SPAN style="COLOR: blue"&gt;case &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;ExpressionType&lt;/SPAN&gt;.MemberAccess:
                &lt;SPAN style="COLOR: #2b91af"&gt;MemberInfo &lt;/SPAN&gt;propertyInfo = ((&lt;SPAN style="COLOR: #2b91af"&gt;MemberExpression&lt;/SPAN&gt;) propertySelector).Member;
                &lt;SPAN style="COLOR: blue"&gt;return &lt;/SPAN&gt;propertyInfo.Name;

            &lt;SPAN style="COLOR: blue"&gt;case &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;ExpressionType&lt;/SPAN&gt;.Call:
                &lt;SPAN style="COLOR: #2b91af"&gt;MethodCallExpression &lt;/SPAN&gt;methodCallExpression = (&lt;SPAN style="COLOR: #2b91af"&gt;MethodCallExpression&lt;/SPAN&gt;) propertySelector;
                &lt;SPAN style="COLOR: blue"&gt;if &lt;/SPAN&gt;(IsSubInclude(methodCallExpression.Method)) &lt;SPAN style="COLOR: green"&gt;// check that it's a SubInclude call
                &lt;/SPAN&gt;{
                    &lt;SPAN style="COLOR: green"&gt;// argument 0 is the expression to which the SubInclude is applied (this could be member access or another SubInclude)
                    // argument 1 is the expression to apply to get the included property
                    // Pass both to BuildString to get the full expression
                    &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;return &lt;/SPAN&gt;BuildString(methodCallExpression.Arguments[0]) + &lt;SPAN style="COLOR: #a31515"&gt;"." &lt;/SPAN&gt;+
                           BuildString(methodCallExpression.Arguments[1]);
                }
                &lt;SPAN style="COLOR: green"&gt;// else drop out and throw
                &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;break&lt;/SPAN&gt;;
        }
        &lt;SPAN style="COLOR: blue"&gt;throw new &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;InvalidOperationException&lt;/SPAN&gt;(&lt;SPAN style="COLOR: #a31515"&gt;"Expression must be a member expression or an SubInclude call: " &lt;/SPAN&gt;+ propertySelector.ToString());

    }

    &lt;SPAN style="COLOR: blue"&gt;private static readonly &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;MethodInfo&lt;/SPAN&gt;[] SubIncludeMethods;
    &lt;SPAN style="COLOR: blue"&gt;static &lt;/SPAN&gt;ObjectQueryExtensions()
    {
        &lt;SPAN style="COLOR: #2b91af"&gt;Type &lt;/SPAN&gt;type = &lt;SPAN style="COLOR: blue"&gt;typeof &lt;/SPAN&gt;(&lt;SPAN style="COLOR: #2b91af"&gt;ObjectQueryExtensions&lt;/SPAN&gt;);
        SubIncludeMethods = type.GetMethods().Where(mi =&amp;gt; mi.Name == &lt;SPAN style="COLOR: #a31515"&gt;"SubInclude"&lt;/SPAN&gt;).ToArray();
    }
    &lt;SPAN style="COLOR: blue"&gt;private static bool &lt;/SPAN&gt;IsSubInclude(&lt;SPAN style="COLOR: #2b91af"&gt;MethodInfo &lt;/SPAN&gt;methodInfo)
    {
        &lt;SPAN style="COLOR: blue"&gt;if &lt;/SPAN&gt;(methodInfo.IsGenericMethod)
        {
            &lt;SPAN style="COLOR: blue"&gt;if &lt;/SPAN&gt;(!methodInfo.IsGenericMethodDefinition)
            {
                methodInfo = methodInfo.GetGenericMethodDefinition();
            }
        }
        &lt;SPAN style="COLOR: blue"&gt;return &lt;/SPAN&gt;SubIncludeMethods.Contains(methodInfo);
    }

    &lt;SPAN style="COLOR: blue"&gt;public static &lt;/SPAN&gt;TPropType SubInclude&amp;lt;TSource, TPropType&amp;gt;(&lt;SPAN style="COLOR: blue"&gt;this &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;EntityCollection&lt;/SPAN&gt;&amp;lt;TSource&amp;gt; source, &lt;SPAN style="COLOR: #2b91af"&gt;Expression&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: #2b91af"&gt;Func&lt;/SPAN&gt;&amp;lt;TSource, TPropType&amp;gt;&amp;gt; propertySelector)
        &lt;SPAN style="COLOR: blue"&gt;where &lt;/SPAN&gt;TSource : &lt;SPAN style="COLOR: blue"&gt;class&lt;/SPAN&gt;, &lt;SPAN style="COLOR: #2b91af"&gt;IEntityWithRelationships
        &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;where &lt;/SPAN&gt;TPropType : &lt;SPAN style="COLOR: blue"&gt;class
    &lt;/SPAN&gt;{
        &lt;SPAN style="COLOR: blue"&gt;throw new &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;InvalidOperationException&lt;/SPAN&gt;(&lt;SPAN style="COLOR: #a31515"&gt;"This method is only intended for use with ObjectQueryExtensions.Include to generate expressions trees"&lt;/SPAN&gt;); &lt;SPAN style="COLOR: green"&gt;// no actually using this - just want the expression!
    &lt;/SPAN&gt;}
    &lt;SPAN style="COLOR: blue"&gt;public static &lt;/SPAN&gt;TPropType SubInclude&amp;lt;TSource, TPropType&amp;gt;(&lt;SPAN style="COLOR: blue"&gt;this &lt;/SPAN&gt;TSource source, &lt;SPAN style="COLOR: #2b91af"&gt;Expression&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: #2b91af"&gt;Func&lt;/SPAN&gt;&amp;lt;TSource, TPropType&amp;gt;&amp;gt; propertySelector)
        &lt;SPAN style="COLOR: blue"&gt;where &lt;/SPAN&gt;TSource : &lt;SPAN style="COLOR: blue"&gt;class&lt;/SPAN&gt;, &lt;SPAN style="COLOR: #2b91af"&gt;IEntityWithRelationships
        &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;where &lt;/SPAN&gt;TPropType : &lt;SPAN style="COLOR: blue"&gt;class
    &lt;/SPAN&gt;{
        &lt;SPAN style="COLOR: blue"&gt;throw new &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;InvalidOperationException&lt;/SPAN&gt;(&lt;SPAN style="COLOR: #a31515"&gt;"This method is only intended for use with ObjectQueryExtensions.Include to generate expressions trees"&lt;/SPAN&gt;); &lt;SPAN style="COLOR: green"&gt;// no actually using this - just want the expression!
    &lt;/SPAN&gt;}
}&lt;/PRE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;&lt;/BLOCKQUOTE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P&gt;This code still has the Include method with the original signature, and adds a couple of SubInclude extension methods. You can see that the code to extract the property name has been pulled out into a separate method (BuildString). This now also handles some additional NodeTypes so that we can handle the SubInclude calls inside the Include call. There are some checks in to ensure that we are dealing with the SubInclude calls at this point (using the IsSubInclude method). With this code, we can write the previous query as well as:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;var &lt;/SPAN&gt;query = &lt;SPAN style="COLOR: blue"&gt;from &lt;/SPAN&gt;customer &lt;SPAN style="COLOR: blue"&gt;in &lt;/SPAN&gt;context.Customers.Include(c =&amp;gt; &lt;STRONG&gt;c.Orders.SubInclude(o =&amp;gt; o.Order_Details).SubInclude(od=&amp;gt;od.Products)&lt;/STRONG&gt;)
            &lt;SPAN style="COLOR: blue"&gt;where &lt;/SPAN&gt;customer.Orders.Count &amp;gt; 0
            &lt;SPAN style="COLOR: blue"&gt;select &lt;/SPAN&gt;customer;&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P&gt;This query includes the Orders, Order Details, and Products as if we’d called Include(“Orders.Order_Details.Product”) and in fact this is what the code will do! Additionally, it doesn’t matter whether you chain the SubInclude calls (as above) or nest them:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;var &lt;/SPAN&gt;query = &lt;SPAN style="COLOR: blue"&gt;from &lt;/SPAN&gt;customer &lt;SPAN style="COLOR: blue"&gt;in &lt;/SPAN&gt;context.Customers.Include(c =&amp;gt; c.Orders.SubInclude(o =&amp;gt; o.Order_Details&lt;STRONG&gt;.SubInclude(od =&amp;gt; od.Products)&lt;/STRONG&gt;))
            &lt;SPAN style="COLOR: blue"&gt;where &lt;/SPAN&gt;customer.Orders.Count &amp;gt; 0
            &lt;SPAN style="COLOR: blue"&gt;select &lt;/SPAN&gt;customer;&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P&gt;Both of these queries have the same effect, so it’s up to you which style you prefer.&lt;/P&gt;
&lt;P&gt;The code isn’t production ready (and as always, is subject to the standard disclaimer: “These postings are provided "AS IS" with no warranties, and confer no rights. Use of included script samples are subject to the terms specified at &lt;A href="http://www.microsoft.com/info/cpyright.htm" mce_href="http://www.microsoft.com/info/cpyright.htm"&gt;http://www.microsoft.com/info/cpyright.htm&lt;/A&gt;”). However, there are a couple of other features that I think are worth briefly mentioning:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;The IsSubInclude function works against a cached MethodInfos for the SubInclude methods. Because these methods are generic, we have to get the generic method definition to test for comparison &lt;/LI&gt;
&lt;LI&gt;The SubInclude functions are not intended to be called at runtime - they are purely there to get the compiler to generate the necessary expression tree! &lt;/LI&gt;
&lt;LI&gt;Generic type inference is at work when we write the queries. Notice that we could write Include(c =&amp;gt; c.Orders) rather than Include&amp;lt;Customer&amp;gt;(c =&amp;gt; c.Orders). Imagine how much less readable the code would become, especially when including multiple levels. &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;I found it quite interesting putting this code together as it pulls in Extension Methods, LINQ To Entities and Expression Trees. The inspiration for this came from the LinkExtensions.ActionLink methods in &lt;A href="http://www.asp.net/mvc/" mce_href="http://www.asp.net/mvc/"&gt;ASP.Net MVC framework&lt;/A&gt; which do the same sort of thing for ActionLinks. I'’m not sure if I’m entirely satisfied with the syntax for including multiple levels, but it is the best I’ve come up with so far. If you’ve any suggestions for how to improve it then let me know!&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8901739" width="1" height="1"&gt;</content><author><name>stuartle</name><uri>http://blogs.msdn.com/members/stuartle.aspx</uri></author><category term="LINQ" scheme="http://blogs.msdn.com/stuartleeks/archive/tags/LINQ/default.aspx" /><category term="CSharp" scheme="http://blogs.msdn.com/stuartleeks/archive/tags/CSharp/default.aspx" /><category term="Extension methods" scheme="http://blogs.msdn.com/stuartleeks/archive/tags/Extension+methods/default.aspx" /></entry></feed>