<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Stuart Leeks : Extension methods</title><link>http://blogs.msdn.com/stuartleeks/archive/tags/Extension+methods/default.aspx</link><description>Tags: Extension methods</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>Improving ObjectQuery&lt;T&gt;.Include – Updated</title><link>http://blogs.msdn.com/stuartleeks/archive/2009/04/24/improving-objectquery-t-include-updated.aspx</link><pubDate>Fri, 24 Apr 2009 14:25:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9566779</guid><dc:creator>stuartle</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/stuartleeks/comments/9566779.aspx</comments><wfw:commentRss>http://blogs.msdn.com/stuartleeks/commentrss.aspx?PostID=9566779</wfw:commentRss><description>&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;P&gt;&lt;STRONG&gt;&lt;/STRONG&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;UPDATE&lt;/STRONG&gt;: &lt;A href="http://blogs.msdn.com/alexj" mce_href="http://blogs.msdn.com/alexj"&gt;Alex James&lt;/A&gt; has a great post on &lt;A href="http://blogs.msdn.com/alexj/archive/2009/07/25/tip-28-how-to-implement-include-strategies.aspx" mce_href="http://blogs.msdn.com/alexj/archive/2009/07/25/tip-28-how-to-implement-include-strategies.aspx"&gt;Eager Loading Strategies&lt;/A&gt; that I'd recommend reading.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9566779" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/stuartleeks/archive/tags/LINQ/default.aspx">LINQ</category><category domain="http://blogs.msdn.com/stuartleeks/archive/tags/Extension+methods/default.aspx">Extension methods</category></item><item><title>DataServiceQuery&lt;T&gt;.Expand</title><link>http://blogs.msdn.com/stuartleeks/archive/2008/09/15/dataservicequery-t-expand.aspx</link><pubDate>Mon, 15 Sep 2008 11:25:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8952213</guid><dc:creator>stuartle</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/stuartleeks/comments/8952213.aspx</comments><wfw:commentRss>http://blogs.msdn.com/stuartleeks/commentrss.aspx?PostID=8952213</wfw:commentRss><description>&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;</description><category domain="http://blogs.msdn.com/stuartleeks/archive/tags/LINQ/default.aspx">LINQ</category><category domain="http://blogs.msdn.com/stuartleeks/archive/tags/CSharp/default.aspx">CSharp</category><category domain="http://blogs.msdn.com/stuartleeks/archive/tags/Extension+methods/default.aspx">Extension methods</category><category domain="http://blogs.msdn.com/stuartleeks/archive/tags/ADO.Net+Data+Services/default.aspx">ADO.Net Data Services</category></item><item><title>Improving ObjectQuery&lt;T&gt;.Include</title><link>http://blogs.msdn.com/stuartleeks/archive/2008/08/27/improving-objectquery-t-include.aspx</link><pubDate>Thu, 28 Aug 2008 01:35:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8901739</guid><dc:creator>stuartle</dc:creator><slash:comments>13</slash:comments><comments>http://blogs.msdn.com/stuartleeks/comments/8901739.aspx</comments><wfw:commentRss>http://blogs.msdn.com/stuartleeks/commentrss.aspx?PostID=8901739</wfw:commentRss><description>&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;</description><category domain="http://blogs.msdn.com/stuartleeks/archive/tags/LINQ/default.aspx">LINQ</category><category domain="http://blogs.msdn.com/stuartleeks/archive/tags/CSharp/default.aspx">CSharp</category><category domain="http://blogs.msdn.com/stuartleeks/archive/tags/Extension+methods/default.aspx">Extension methods</category></item></channel></rss>