<?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">Vitek&amp;#39;s Blog</title><subtitle type="html" /><id>http://blogs.msdn.com/b/vitek/atom.aspx</id><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/vitek/" /><link rel="self" type="application/atom+xml" href="http://blogs.msdn.com/b/vitek/atom.aspx" /><generator uri="http://telligent.com" version="5.6.50428.7875">Telligent Evolution Platform Developer Build (Build: 5.6.50428.7875)</generator><updated>2010-02-23T21:51:00Z</updated><entry><title>Custom paging provider</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/vitek/archive/2012/06/04/custom-paging-provider.aspx" /><id>http://blogs.msdn.com/b/vitek/archive/2012/06/04/custom-paging-provider.aspx</id><published>2012-06-04T14:08:28Z</published><updated>2012-06-04T14:08:28Z</updated><content type="html">&lt;p&gt;The OData protocol supports a feature called Server driven paging. It is used to limit the amount of data client can query with a single request while still providing a way from the client to get all the data (in multiple requests). A more detailed explanation is for available for example in this &lt;a href="http://blogs.msdn.com/b/astoriateam/archive/2009/03/19/ado-net-data-services-v1-5-ctp1-server-driven-paging.aspx"&gt;blog post&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;WCF Data Services implements this in two possible ways. The easy to use built-in server driven paging implementation and the more complicated but powerful custom paging. The built-in server driven paging implementation simply puts a limit on the number of results returned for a specified entity set. The way to set it up and use it is described for example &lt;a href="http://msdn.microsoft.com/en-us/library/ee473424.aspx"&gt;here&lt;/a&gt; or &lt;a href="http://blogs.msdn.com/b/phaniraj/archive/2010/04/25/server-driven-paging-with-wcf-data-services.aspx"&gt;here&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;But the protocol allows the server to split the results into multiple pages in any way, not just number of results. In fact clients don’t know how the server decided when to split the results. So you may want to limit the time it takes to execute the query, or the amount of memory consumed or maybe even limit the query on a subset of nodes (in a distributed system) and return a page per node, and so on. To support these scenarios the WCF Data Services allows custom implementation of the server driven paging. It is done by implementing the IDataServicePagingProvider interface. Let’s take a look how that might work.&lt;/p&gt;  &lt;h2&gt;Prerequisites&lt;/h2&gt;  &lt;p&gt;Custom paging can only be implemented if our service already implements custom metadata and query providers (IDataServiceMetadataProvider and IDataServiceQueryProvider). For samples on these take a look at this &lt;a href="http://blogs.msdn.com/b/alexj/archive/2010/01/07/data-service-providers-getting-started.aspx"&gt;great series of posts&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;The custom query provider will also have to implement custom IQueryable. We typically already have this when we implement custom metadata and query provider, but it’s not a requirement. For custom paging this is absolutely a requirement as there’s no practical way how to tweak the existing IQueryable implementations (like LINQ to EF, LINQ to SQL, LINQ to Objects, …) for this purpose. On the other hand, there’s nothing preventing us from implementing the IQueryable as a layer over an existing implementation.&lt;/p&gt;  &lt;p&gt;And finally we implement the IDataServicePagingProvider interface and return its implementation from our IServiceProvider. The easiest way to describe how to implement the two methods the interface has is to describe the steps which the WCF Data Services takes to process paged queries.&lt;/p&gt;  &lt;h2&gt;How does it work&lt;/h2&gt;  &lt;p&gt;Let’s walk through a query processing for a simple query to /Customers.&lt;/p&gt;  &lt;h3&gt;1 – Request for the entity set&lt;/h3&gt;  &lt;p&gt;Client sends a request to the service for /Customers.&lt;/p&gt;  &lt;h3&gt;2 – Query processing&lt;/h3&gt;  &lt;p&gt;On the server the query gets processed and eventually is passed to the custom IQueryable implementation. This implementation must know that for Customers set the service should return paged results and should produce a query for the first page of the results.&lt;/p&gt;  &lt;p&gt;This part depends on the paging behavior we need to implement. We may modify the query to prepare the underlying storage for the paging. We may also need to inject some filter or limit into the query. For example the built-in paging implementation will add sorting to the query by key properties, so that it gets stable order of results and then it will request only the first page of results (by taking first n results).&lt;/p&gt;  &lt;h3&gt;3 – Enumeration of results&lt;/h3&gt;  &lt;p&gt;When the query executes the IQueryable.GetEnumerator gets called. Since we have a custom IQueryable implementation we get called here. We need to return a custom enumerator which will only return the first page of results. The end of the page is marked by simply reporting no more results from the enumeration.&lt;/p&gt;  &lt;p&gt;Depending on how we chose to limit the page of results this may be a trivial operation (if the limit was built into the query by our IQueryable) or this may actually do the real work. For example here we could measure the time it takes to compute the results and decide to end the page if it takes too long. Note that it’s perfectly fine to return no results (clients will expect this).&lt;/p&gt;  &lt;p&gt;No matter which approach we take the important part is that the enumeration must somehow track where it ended in the bigger result set (the one with all the results, the non-paged one).&lt;/p&gt;  &lt;h3&gt;4 – Getting the continuation token&lt;/h3&gt;  &lt;p&gt;Once the IEnumerator returns no more results, the WCF Data Services will call IDataServicePagingProvider.GetContinuationToken and pass in the enumerator. Now we need to extract the information of how far we got through the results from the enumerator and serialize it as an array of primitive values and return it.&lt;/p&gt;  &lt;p&gt;The GetContinuationToken returns an array of objects. These need to be primitive values (as recognized by OData) and they should be reasonably small since since all of those will be written into the URL.&lt;/p&gt;  &lt;p&gt;The continuation token must fulfill several requirements:&lt;/p&gt;  &lt;p&gt;- It must not be temporary, clients can in theory hold on to it indefinitely. We may choose to only support certain lifetime, but it needs to be rather long (typical user sessions or something similar). The best would be to have indefinite lifetime of the continuation tokens.&lt;/p&gt;  &lt;p&gt;- It must be persisted – that means it should not rely on any transient data on the server side. For example, storing some table in memory on the server. There’s no guarantee that the client will not ask for the next page after the server process was restarted, or maybe the next request will be processed by a different server in the farm and so on.&lt;/p&gt;  &lt;p&gt;- It must “make progress”. If we don’t return any results for any given page, the continuation token should contain enough information so that next time we can pick up from where we ended without trying to compute the entire page again. Otherwise this may lead to endless loop. So for example if the page is limited by the amount of time it took to process the query, the continuation token must somehow remember how far the query processing got even if it didn’t return any results.&lt;/p&gt;  &lt;p&gt;- It should be reusable. There’s nothing prevent the client from asking for the same next page multiple times.&lt;/p&gt;  &lt;h3&gt;5 – Response to the client&lt;/h3&gt;  &lt;p&gt;The service serializes the returned continuation token into the $skiptoken query option and returns it as part of the next link to the client. Let’s say that we produce the next link as /Customers?$skiptoken=1234.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;some time later…&lt;/p&gt;  &lt;h3&gt;6 – Client requests the next page&lt;/h3&gt;  &lt;p&gt;The client sends a request for the next page using the next link it got. So for example /Customers?$skiptoken=1234.&lt;/p&gt;  &lt;h3&gt;7 – Processing the next page query&lt;/h3&gt;  &lt;p&gt;The services processes the query as usual building our custom IQueryable as usual.&lt;/p&gt;  &lt;h3&gt;8 – Applying the continuation token&lt;/h3&gt;  &lt;p&gt;At one point during the query processing the service will call the IDataServicePagingProvider.SetContinuationToken. It will pass in the IQueryable it built so far and the continuation token. The continuation token is deserialized from the URL and will contain the values returned by some previous call to GetContinuationToken.&lt;/p&gt;  &lt;p&gt;The method needs to “apply” the continuation token to the query. The goal is to modify the query such that it will continue from where it left of as described by the continuation token and return the next page of results.&lt;/p&gt;  &lt;p&gt;Couple of notes on implementing this:&lt;/p&gt;  &lt;p&gt;- The SetContinuationToken doesn’t return a new IQueryable, the implementation is expected to modify the existing IQueryable.&lt;/p&gt;  &lt;p&gt;- Because the IQueryable might be used for further query construction, the best approach is to just stick the continuation token onto the IQueryable at this time without applying it to the query. And then apply it before the query gets executed and once we are sure we have the entire query.&lt;/p&gt;  &lt;h3&gt;9 – Enumeration of next page results&lt;/h3&gt;  &lt;p&gt;The service executes the query and enumerates its results. This should be again limited to a one page of results and the enumerator should stop after it hits the page limit.&lt;/p&gt;  &lt;h3&gt;10 – Producing next-next page link&lt;/h3&gt;  &lt;p&gt;As in #4 above the GetContinuationToken is called on the enumerator. If it returns a continuation token, the entire process repeats itself just like in #4 above. If the method returns null (no continuation token), the service will not produce any next link into the results and the client will determine that it got all the results for the query.&lt;/p&gt;  &lt;h2&gt;Additional considerations&lt;/h2&gt;  &lt;p&gt;The query might be more complicated that just a simple /Customers. It may contain filters, sorting, projections and so on. The WCF Data Service will include all of these query options in the next link automatically, so the continuation token doesn’t have to remember these.&lt;/p&gt;  &lt;p&gt;The paged entity set might not be the top-most entity set of the results for a given query. For example a query like /Regions?$expand=Customers will also returns custom result set. It is a responsibility of the IQueryable to recognize this and apply the paging limits to the expansions as well. And as above once it returns the enumerator for the expanded set and the enumerator returns no more results, the service will call GetContinuationToken on it to get the continuation token for the inner set.&lt;/p&gt;  &lt;p&gt;So the GetContinuationToken might get called multiple times during a single query processing. Once for the top-most result set and once for each expanded result set. The SetContinuationToken is only ever called once for a query, and only if it did contain the $skiptonen query option.&lt;/p&gt;  &lt;p&gt;Once the IDataServicePagingProvider is implemented, the built-in paging provider is disabled. The SetEntitySetPageSize methods will do nothing then. So it’s either all custom, or all built-in.&lt;/p&gt;  &lt;p&gt;If we don’t want to implement paging on a specified entity set, we just return null from the GetContinuationToken when called on the enumeration of such entity set.&lt;/p&gt;  &lt;p&gt;All in all, implementing the custom paging provider is a complex task. But it opens very interesting and powerful techniques for the service.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10314683" width="1" height="1"&gt;</content><author><name>Vitek Karas - MSFT</name><uri>http://blogs.msdn.com/vitkaras/ProfileUrlRedirect.ashx</uri></author></entry><entry><title>Projections in custom providers – Simple solution</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/vitek/archive/2012/01/07/projections-in-custom-providers-simple-solution.aspx" /><id>http://blogs.msdn.com/b/vitek/archive/2012/01/07/projections-in-custom-providers-simple-solution.aspx</id><published>2012-01-07T18:17:09Z</published><updated>2012-01-07T18:17:09Z</updated><content type="html">&lt;p&gt;Implementing custom provider for WCF Data Services is complicated enough. The fact that for the really interesting providers it’s also necessary to implement a custom IQueryable makes things just so much more complicated. Based on feedback from multiple parties trying to implement the IQueryable for WCF Data Services one of the most challenging tasks is to support projections and expansions. These are hard not only because the expression trees generated for them are complicated but also because they require the query to return results in different shape than usual. In this post we’ll walk through a simple case of dealing with projection and expansions (with some limitations).&lt;/p&gt;  &lt;p&gt;First let’s assume that you’re familiar with the expression trees generated by WCF Data Services for projections and expansions. These are described in the &lt;a href="http://blogs.msdn.com/b/vitek/archive/2010/02/25/data-services-expressions-part-1-intro.aspx"&gt;Data Services Expressions series&lt;/a&gt; &lt;a href="http://blogs.msdn.com/b/vitek/archive/2010/07/07/data-services-expressions-part-8-projections.aspx"&gt;part 8&lt;/a&gt; and &lt;a href="http://blogs.msdn.com/b/vitek/archive/2010/07/15/data-services-expressions-part-9-expansions.aspx?wa=wsignin1.0"&gt;part 9&lt;/a&gt;. Also some familiarity with IQueryable, its behavior and the general approaches to its implementation is required. There are multiple places to learn about these, but the classic source is Matt’s blog &lt;a href="http://blogs.msdn.com/b/mattwar/archive/2007/07/30/linq-building-an-iqueryable-provider-part-i.aspx"&gt;series&lt;/a&gt;.&lt;/p&gt;  &lt;h2&gt;Scenarios&lt;/h2&gt;  &lt;p&gt;Since the solution we’re going to try out is simplistic it only solves certain limited scenarios. Projections ($select) are meant to limit the number of properties returned by a query for any given entity in it. This is definitely useful for the client since it can download only the properties it’s going to need. But the server can take advantage of this as well, since if the client only asks for subset of properties the server can also only load a subset of properties from the underlying data store. The simple solution described in this post assumes that the second optimization is not necessary, that it’s OK to load all properties for each entity from the data store. The projections then only happen inside the service and are easier to deal with.&lt;/p&gt;  &lt;p&gt;If your provider wants to support expansions as well, these are even more complicated. This simple solution will only support expansions if the entity instances can load the target of any given navigation property on demand (when the navigation property is accessed). Some data sources might be able to do this easily, but for other it might be hard or expensive. I will discuss possible solutions to those in some later post.&lt;/p&gt;  &lt;h2&gt;Simplification&lt;/h2&gt;  &lt;p&gt;The general idea of dealing with projections in our provider will be this:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Take the entire query and split it in two parts, the projection and expansion itself and the source query for the projection and expansion which returns the results as plain entities. &lt;/li&gt;    &lt;li&gt;Then run the source query against the underlying data source (we will assume we already have a solution for this). &lt;/li&gt;    &lt;li&gt;Take the results of the source query and apply projections and expansions on it inside the service. &lt;/li&gt;    &lt;li&gt;Return the new results to WCF Data Services. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;For the purposes of this sample we will use a LINQ to SQL based data source. So we create a new web application, add a database to it with two tables Products and Categories (similar schema as in the &lt;a href="http://services.odata.org/OData/OData.svc/"&gt;sample service&lt;/a&gt; on odata.org). Then we create a LINQ to SQL classes over these tables which will give us a SampleDataContext class with two properties Products and Categories.&lt;/p&gt;  &lt;p&gt;&lt;font color="#666666"&gt;Note: I chose LINQ to SQL since it can deal with all the other parts of the query (filters, sorting and so on). It also supports on-demand loading of navigation properties by just accessing them. And last but not least, it generates the proxy classes, so we can use reflection provider to setup the metadata for us. In custom provider implementations this would obviously not be the case and most of these would have to solve in our code, but for the purposes of this sample such an approach is enough.&lt;/font&gt;&lt;/p&gt;  &lt;h2&gt;Custom query provider&lt;/h2&gt;  &lt;p&gt;We need a custom query provider, that is IQueryable and IQueryProvider implementations. Implementation of IQueryable is pretty simple (as usual):&lt;/p&gt;  &lt;div id="codeSnippetWrapper"&gt;   &lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;     &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; ProjectionQuery&amp;lt;T&amp;gt; : IOrderedQueryable&amp;lt;T&amp;gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;{&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; Expression expression;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; ProjectionQueryProvider provider;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&amp;#160;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; ProjectionQuery(ProjectionQueryProvider provider, Expression expression)&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;    {&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.provider = provider;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.expression = expression;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;    }&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&amp;#160;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; IEnumerator&amp;lt;T&amp;gt; GetEnumerator()&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;    {&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.provider.ExecuteQuery&amp;lt;T&amp;gt;(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.expression);&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;    }&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&amp;#160;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;    IEnumerator IEnumerable.GetEnumerator()&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;    {&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.provider.ExecuteQuery&amp;lt;T&amp;gt;(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.expression);&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;    }&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&amp;#160;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; Type ElementType { get { &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(T); } }&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&amp;#160;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; Expression Expression { get { &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.expression; } }&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&amp;#160;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; IQueryProvider Provider { get { &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.provider; } }&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;}&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;When a query is to be execute this only calls ExecuteQuery method on the query provider. Now let’s add a stock implementation of the query provider like this:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; ProjectionQueryProvider : IQueryProvider&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;{&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; IQueryProvider dataSourceQueryProvider;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&amp;#160;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; ProjectionQueryProvider(IQueryProvider dataSourceQueryProvider)&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;    {&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;        &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.dataSourceQueryProvider = dataSourceQueryProvider;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;    }&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&amp;#160;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; IQueryable&amp;lt;T&amp;gt; WrapDataSourceQuery&amp;lt;T&amp;gt;(IQueryable&amp;lt;T&amp;gt; dataSourceQuery)&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;    {&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; ProjectionQuery&amp;lt;T&amp;gt;(&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;            &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; ProjectionQueryProvider(dataSourceQuery.Provider),&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;            dataSourceQuery.Expression);&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;    }&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&amp;#160;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; IQueryable&amp;lt;TElement&amp;gt; CreateQuery&amp;lt;TElement&amp;gt;(Expression expression)&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;    {&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; ProjectionQuery&amp;lt;TElement&amp;gt;(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;, expression);&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;    }&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&amp;#160;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; IQueryable CreateQuery(Expression expression)&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;    {&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; (IQueryable)Activator.CreateInstance(&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;            &lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(ProjectionQuery&amp;lt;&amp;gt;).MakeGenericType(TypeSystem.GetIEnumerableElementType(expression.Type)),&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;            &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;,&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;            expression);&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;    }&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&amp;#160;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; TResult Execute&amp;lt;TResult&amp;gt;(Expression expression)&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;    {&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;        &lt;span style="color: #008000"&gt;// This is the case of for example .Count() query&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;        &lt;span style="color: #008000"&gt;// - we don't support it for now.&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;        &lt;span style="color: #008000"&gt;// One option would be to pass it directly to the underlying provider&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;        &lt;span style="color: #008000"&gt;// if it can handle it.&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;        &lt;span style="color: #0000ff"&gt;throw&lt;/span&gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; NotSupportedException(&lt;span style="color: #006080"&gt;&amp;quot;We don't support expressions returning simple values yet.&amp;quot;&lt;/span&gt;);&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;    }&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&amp;#160;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;object&lt;/span&gt; Execute(Expression expression)&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;    {&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;        &lt;span style="color: #008000"&gt;// This is the case of for example .Count() query        &lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;        &lt;span style="color: #008000"&gt;// - we don't support it for now.&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;        &lt;span style="color: #008000"&gt;// One option would be to pass it directly to the underlying provider&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;        &lt;span style="color: #008000"&gt;// if it can handle it.&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;        &lt;span style="color: #0000ff"&gt;throw&lt;/span&gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; NotSupportedException(&lt;span style="color: #006080"&gt;&amp;quot;We don't support expressions returning simple values yet.&amp;quot;&lt;/span&gt;);&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;    }&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&amp;#160;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #008000"&gt;// ExecuteQuery implementation missing here.&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;}&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Our query provider is based on a query provider for the underlying data source. As noted above this assumes that we already have an IQueryable implementation which can deal with filters, sorting and alike.&lt;/p&gt;

&lt;h2&gt;Projections&lt;/h2&gt;

&lt;p&gt;And now to the real interesting part, how to implement the ExecuteQuery:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; IEnumerator&amp;lt;TElement&amp;gt; ExecuteQuery&amp;lt;TElement&amp;gt;(Expression expression)&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;{&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #008000"&gt;// Simple solution, more robust solution would be using expression visitor&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #008000"&gt;// to process the projection and separate the projection source&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #008000"&gt;// from the rest of the query.&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #008000"&gt;// For now assume that the projection is the last operator on the query&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #008000"&gt;// (which is mostly true for WCF DS Expressions)&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&amp;#160;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #008000"&gt;// Match the .Select call (this is a helper method which determines&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #008000"&gt;// if the method call is a .Select and extracts the parameters&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #008000"&gt;// to the Select call in a nicely consumable way,&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #008000"&gt;// it doesn't modify the expression in any way).&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;    var selectMatch = ExpressionUtils.MatchSelectCall(expression);&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&amp;#160;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (selectMatch == &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;)&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;    {&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;        &lt;span style="color: #008000"&gt;// No projection - just run the source query.&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.dataSourceQueryProvider.CreateQuery&amp;lt;TElement&amp;gt;(expression)&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;            .GetEnumerator();&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;    }&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #0000ff"&gt;else&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;    {&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;        &lt;span style="color: #008000"&gt;// Projection - separate the source query, and run that&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;        &lt;span style="color: #008000"&gt;// against the data source provider.&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;        &lt;span style="color: #008000"&gt;// Call a private method so that we can use generics&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;        &lt;span style="color: #008000"&gt;// for easier manipulation of results&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;        &lt;span style="color: #008000"&gt;// (otherwise we would have to use a lot of reflection)&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;        &lt;span style="color: #008000"&gt;// The source item type is the item type of the source expression.&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;        MethodInfo methodInfo = &lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(ProjectionQueryProvider)&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;            .GetMethod(&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;                &lt;span style="color: #006080"&gt;&amp;quot;ProcessProjection&amp;quot;&lt;/span&gt;,&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;                BindingFlags.Instance | BindingFlags.NonPublic)&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;            .MakeGenericMethod(&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;                TypeSystem.GetIEnumerableElementType(selectMatch.Source.Type),&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;                &lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(TElement));&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; (IEnumerator&amp;lt;TElement&amp;gt;)methodInfo.Invoke(&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;            &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;,&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;            &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #0000ff"&gt;object&lt;/span&gt;[] { selectMatch });&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;    }&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;} &lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&amp;#160;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; IEnumerator&amp;lt;TResultElement&amp;gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;     ProcessProjection&amp;lt;TSourceElement, TResultElement&amp;gt;(&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;        ExpressionUtils.SelectCallMatch selectMatch)&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;{&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #008000"&gt;// Source is the query without projection/expansion&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #008000"&gt;// So we will run it right here against the original provider&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #008000"&gt;// - this is the query without projections.&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;    IQueryable&amp;lt;TSourceElement&amp;gt; dataSourceQuery =&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;         &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.dataSourceQueryProvider.CreateQuery&amp;lt;TSourceElement&amp;gt;(selectMatch.Source);&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&amp;#160;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #008000"&gt;// This turns the query into enumerable which effectively executes it.&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #008000"&gt;// All other LINQ operations we perform on top of it&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #008000"&gt;// are performed on LINQ to Objects and not the underlying query provider.&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #008000"&gt;// (We could also cache the results here if needed).&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;    IEnumerable&amp;lt;TSourceElement&amp;gt; dataSourceQueryResults =&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;        dataSourceQuery.AsEnumerable(); ;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&amp;#160;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #008000"&gt;// Now we have the results of the query as whole entities&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #008000"&gt;// (no projection applied).&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #008000"&gt;// This also assumes that for $expand to work the entities returned&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #008000"&gt;// already have or can lazy load the navigation properties.&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #008000"&gt;// Get the projection lambda and compile it into a delegate.&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;    Func&amp;lt;TSourceElement, TResultElement&amp;gt; projectionFunc =&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;        (Func&amp;lt;TSourceElement, TResultElement&amp;gt;)selectMatch.Lambda.Compile();&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&amp;#160;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #008000"&gt;// And now just run the projection function on each item&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #008000"&gt;// from the results we have to create the real results.&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;    IEnumerable&amp;lt;TResultElement&amp;gt; results =&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;         dataSourceQueryResults.Select(sourceItem =&amp;gt; projectionFunc(sourceItem));&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; results.GetEnumerator();&lt;/pre&gt;
&lt;!--CRLF--&gt;}&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;The ExecuteQuery implementation only determines if the query contains projections/expansions and if so it invokes the ProcessProjection method. That method takes the source of the projection and, executes it against the data source (in our case this would query IQueryable against the LINQ to SQL and run it). Then it takes the results and applies the projections/expansions in-memory on it.&lt;/p&gt;

&lt;p&gt;The main trick used here is to take a lambda expression (System.Linq.Expressions.LambdaExpression) and call the Compile method on it. This generates a lightweight dynamic method which is the body of the .Select and can be called just like any other method. Then we just simply call this method on each result and return to WCF Data Services.&lt;/p&gt;

&lt;h2&gt;Sample&lt;/h2&gt;

&lt;p&gt;And now in our sample we simply wrap the IQueryable returned by LINQ to SQL with the one we implemented above. Like this:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #008000"&gt;// Data context which wraps the LINQ to SQL data context,&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #008000"&gt;// so that we can wrap the IQueryable properties.&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; ProjectionDataContext&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;{&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; SampleDataContext sampleDataContext = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; SampleDataContext();&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&amp;#160;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; IQueryable&amp;lt;Product&amp;gt; Products {&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;         get { &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; ProjectionQueryProvider.WrapDataSourceQuery(&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;                  &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.sampleDataContext.Products); } }&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; IQueryable&amp;lt;Category&amp;gt; Categories {&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;         get { &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; ProjectionQueryProvider.WrapDataSourceQuery(&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;                  &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.sampleDataContext.Categories); } }&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;}&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&amp;#160;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; SampleService : DataService&amp;lt;ProjectionDataContext&amp;gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;{&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; InitializeService(DataServiceConfiguration config)&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;    {&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;        config.SetEntitySetAccessRule(&lt;span style="color: #006080"&gt;&amp;quot;*&amp;quot;&lt;/span&gt;, EntitySetRights.AllRead);&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;        config.DataServiceBehavior.MaxProtocolVersion =&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;            DataServiceProtocolVersion.V2;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;    }&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;}&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;And that’s it. Give it a try and run a query for example like service/Products?$select=Name. It should only return products with Name property. To verify that it really worked, set a breakpoint into the ProcessProjection method on the line which create dataSourceQueryResults and run the query again. The dataSourceQuery is the IQueryable which will execute against the data source. In this sample it should show in the debug window a simple table scan for table Products (this is provided by LINQ to SQL for us). If the query would contain filters or sorting this query would contain all of those and LINQ to SQL would generate the appropriate SQL for it.&lt;/p&gt;

&lt;p&gt;If we would like to use this solution as part of a bigger custom provider the query provider would need to be able to handle all of our custom provider needs on top of this. There are also some technical limitations. In particular the solution requires that IDataServiceQueryProvider.NullPropagationRequire returns true, otherwise the function generated by lambda.Compile would not correctly handle null values. This solution is also not suitable for wrapping EF providers since the expression trees generated for EF provider are not fully compatible with lambda.Compile either. And last, if our custom provider uses untyped properties, those would have to be “resolved” in the lambda expression before the .Compile is called. Not to mention how to solve the expansions for real and don’t lazy load the navigation properties one by one. All this will have to wait for another post.&lt;/p&gt;

&lt;p&gt;And here’s the full sample as a &lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-32-74/6457.ProjectionProviderSimpleSample.zip"&gt;VS 2010 solution&lt;/a&gt;.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10254251" width="1" height="1"&gt;</content><author><name>Vitek Karas - MSFT</name><uri>http://blogs.msdn.com/vitkaras/ProfileUrlRedirect.ashx</uri></author></entry><entry><title>Adding Multi-Value properties to untyped providers</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/vitek/archive/2010/11/09/adding-multi-value-properties-to-untyped-providers.aspx" /><id>http://blogs.msdn.com/b/vitek/archive/2010/11/09/adding-multi-value-properties-to-untyped-providers.aspx</id><published>2010-11-09T10:40:59Z</published><updated>2010-11-09T10:40:59Z</updated><content type="html">&lt;p&gt;With the recent release of the WCF Data Services Oct 2010 CTP1 for .NET4 the WCF Data Services now has the ability to expose Multi-Value properties (formerly called “Bags”). These can come very handy when you want to include short collections of primitive or complex types on your entities (or other complex types). In this blog we’ll take a look at what does it take to add the Multi-Value properties to an untyped provider.&lt;/p&gt;  &lt;p&gt;Naming note: Sometimes in the CTP1 APIs the Multi-Value properties are still referred to as Bags, or Bag properties. Also the EDM type name is still Bag. I will refer to these as Multi-Value properties in the text, but the code might talk about Bags to be consistent with existing APIs.&lt;/p&gt;  &lt;h3&gt;Setup&lt;/h3&gt;  &lt;p&gt;I’m going to be using the untyped read-only provider sample from the OData Provider Toolkit which you can download here: &lt;a title="http://www.odata.org/developers/odata-sdk" href="http://www.odata.org/developers/odata-sdk"&gt;http://www.odata.org/developers/odata-sdk&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;You will also need the WCF Data Services Oct 2010 CTP1 for .NET4 as announced on this blog: &lt;a title="http://blogs.msdn.com/b/astoriateam/archive/2010/10/26/announcing-wcf-data-services-oct-2010-ctp1-for-net4-amp-sl4.aspx" href="http://blogs.msdn.com/b/astoriateam/archive/2010/10/26/announcing-wcf-data-services-oct-2010-ctp1-for-net4-amp-sl4.aspx"&gt;http://blogs.msdn.com/b/astoriateam/archive/2010/10/26/announcing-wcf-data-services-oct-2010-ctp1-for-net4-amp-sl4.aspx&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;In your VS 2010 open the Untyped\RO\ODataDemo.sln solution file and let VS convert it to 2010 format and convert all the projects to .NET4.&lt;/p&gt;  &lt;p&gt;Since the CTP is a side-by-side release it doesn’t replace the WCF Data Services assemblies, so you will need to update the references. Simply open each of the three projects and remove the references to System.Data.Services and System.Data.Services.Client. Then add references to Microsoft.Data.Services.dll and Microsoft.Data.Services.Client.dll which can be found in your installation folder of the CTP under .NETFramework sub-folder. (You will have to browse for the files as the assemblies are not listed in the framework list).&lt;/p&gt;  &lt;p&gt;To verify everything works as expected you should be able to rebuild the solution and run all the tests without issues. You can also browse to the demo service to see it working.&lt;/p&gt;  &lt;h3&gt;Metadata&lt;/h3&gt;  &lt;p&gt;In order to expose Multi-Value property, such property must be added to the metadata. To define a Multi-Value property a special Multi-Value resource type is required. This type is used to define the type of each item of the Multi-Value. The class which represents this type is called BagResourceType, it derives from the ResourceType class and it adds a single property ItemType. To create an instance of this type a new method ResourceType.GetBagResourceType was added.&lt;/p&gt;  &lt;p&gt;Let’s see how this works on the untyped provider toolkit sample. To add a Multi-Value of complex or primitive type add this method to the DSPMetadata class:&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: green"&gt;Adds a bag of complex or primitive items property.&lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/summary&amp;gt;
/// &amp;lt;param name=&amp;quot;resourceType&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color: green"&gt;The resource type to add the property to.&lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/param&amp;gt;
/// &amp;lt;param name=&amp;quot;name&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color: green"&gt;The name of the property to add.&lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/param&amp;gt;
/// &amp;lt;param name=&amp;quot;itemType&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color: green"&gt;The resource type of the item in the bag.&lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/param&amp;gt;
&lt;/span&gt;&lt;span style="color: blue"&gt;public void &lt;/span&gt;AddBagProperty(&lt;span style="color: #2b91af"&gt;ResourceType &lt;/span&gt;resourceType, &lt;span style="color: blue"&gt;string &lt;/span&gt;name, &lt;span style="color: #2b91af"&gt;ResourceType &lt;/span&gt;itemType)
{
    &lt;span style="color: #2b91af"&gt;ResourceProperty &lt;/span&gt;property = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ResourceProperty&lt;/span&gt;(&lt;br /&gt;        name, &lt;br /&gt;        &lt;span style="color: #2b91af"&gt;ResourcePropertyKind&lt;/span&gt;.Bag, &lt;br /&gt;        &lt;span style="color: #2b91af"&gt;ResourceType&lt;/span&gt;.GetBagResourceType(itemType));
    property.CanReflectOnInstanceTypeProperty = &lt;span style="color: blue"&gt;false&lt;/span&gt;;
    resourceType.AddProperty(property);
}&lt;/pre&gt;


&lt;p&gt;Please note that the property must be defined with a special kind Bag as well as have the special BagResourceType type. Also since we’re creating an untyped provider the property is set to not use reflection (as any other property in this provider).&lt;/p&gt;

&lt;p&gt;For a Multi-Value of primitive types we can also add a helper method like this:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: gray"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: green"&gt;Adds a bag of primitive items property.&lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/summary&amp;gt;
/// &amp;lt;param name=&amp;quot;resourceType&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color: green"&gt;The resource type to add the property to.&lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/param&amp;gt;
/// &amp;lt;param name=&amp;quot;name&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color: green"&gt;The name of the property to add.&lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/param&amp;gt;
/// &amp;lt;param name=&amp;quot;itemType&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="color: green"&gt;The primitive CLR type of the item in the bag.&lt;/span&gt;&lt;span style="color: gray"&gt;&amp;lt;/param&amp;gt;
&lt;/span&gt;&lt;span style="color: blue"&gt;public void &lt;/span&gt;AddBagProperty(&lt;span style="color: #2b91af"&gt;ResourceType &lt;/span&gt;resourceType, &lt;span style="color: blue"&gt;string &lt;/span&gt;name, &lt;span style="color: #2b91af"&gt;Type &lt;/span&gt;itemType)
{
    &lt;span style="color: #2b91af"&gt;ResourceType &lt;/span&gt;itemResourceType = &lt;span style="color: #2b91af"&gt;ResourceType&lt;/span&gt;.GetPrimitiveResourceType(itemType);
    &lt;span style="color: blue"&gt;this&lt;/span&gt;.AddBagProperty(resourceType, name, itemResourceType);
}&lt;/pre&gt;


&lt;p&gt;One other thing to note about the Multi-Value properties is their instance type. The InstanceType property of the BagResourceType will always return IEnumerable&amp;lt;T&amp;gt; where T is the InstanceType of the ItemType. So for example a Multi-Value property of strings (primitive type), will have an instance type IEnumerable&amp;lt;string&amp;gt;.&lt;/p&gt;

&lt;p&gt;In the untyped provider in the sample all complex types use the same instance type called DSPResource. So a Multi-Value of complex types will have instance type IEnumerable&amp;lt;DSPResource&amp;gt;.&lt;/p&gt;

&lt;p&gt;The instance type is important because it’s the type the WCF Data Services will assume as the value of the Multi-Value property. Most importantly the IDataServiceQueryProvider.GetPropertyValue method should return an instance of IEnumerable&amp;lt;T&amp;gt; for a Multi-Value property. Note that other than being IEnumerable&amp;lt;T&amp;gt; there are no other requirements on the value returned. It can be really any instance which implements the required interface. For most cases List&amp;lt;T&amp;gt; works great, but if you have some special requirements, you can implement your own and it will work just fine.&lt;/p&gt;

&lt;h3&gt;Data&lt;/h3&gt;

&lt;p&gt;And that leads us to how to specify instance data. Let’s use the sample ODataDemoService for this. In the DemoDSPDataService.svc.cs file there is a method which defines the metadata for the demo service called CreateDSPMetadata. For now, we will tweak the metadata by adding a Tags property to the Product entity. This can be done by adding just a single line like this:&lt;/p&gt;

&lt;pre class="code"&gt;metadata.AddBagProperty(product, &lt;span style="color: #a31515"&gt;&amp;quot;Tags&amp;quot;&lt;/span&gt;, &lt;span style="color: blue"&gt;typeof&lt;/span&gt;(&lt;span style="color: blue"&gt;string&lt;/span&gt;));&lt;/pre&gt;


&lt;p&gt;Add this line after the other property additions for the Product entity type.&lt;/p&gt;

&lt;p&gt;Now we need to add the instance values for the Tags property. Important thing to note is that Multi-Value properties can not have null value. That means the IEnumerable&amp;lt;T&amp;gt; must never be null (if it is, the service will fail to serialize the results). It is also invalid to have items in the Multi-Value of null value, so the enumeration of the IEnumerable&amp;lt;T&amp;gt; must not return nulls either (if the T actually allows nulls).&lt;/p&gt;

&lt;p&gt;The demo service has a method called CreateDataSource which initializes the instance data. So let’s add some instance data for our new Multi-Value property there. Anywhere into the part which sets property values for the productBread add a line like this:&lt;/p&gt;

&lt;pre class="code"&gt;productBread.SetValue(&lt;span style="color: #a31515"&gt;&amp;quot;Tags&amp;quot;&lt;/span&gt;, &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;string&lt;/span&gt;&amp;gt;() { &lt;span style="color: #a31515"&gt;&amp;quot;Bakery&amp;quot;&lt;/span&gt;, &lt;span style="color: #a31515"&gt;&amp;quot;Food&amp;quot; &lt;/span&gt;});&lt;/pre&gt;


&lt;p&gt;Then add similar lines for the productMilk and productWine as well. If you omit these lines the value of the Multi-Value property will be null and it will cause failures (since nulls are not allowed). It is perfectly valid to add empty lists though.&lt;/p&gt;

&lt;h3&gt;Result&lt;/h3&gt;

&lt;p&gt;To run the demo service, one more thing has to be done. The Multi-Value property is a new construct which older clients/servers might not understand so it requires an OData protocol version 3.0. So we need to allow the V3 for our service by changing the InitializeService method to include line like this (replace the line there which sets it to V2):&lt;/p&gt;

&lt;pre class="code"&gt;config.DataServiceBehavior.MaxProtocolVersion = &lt;span style="color: #2b91af"&gt;DataServiceProtocolVersion&lt;/span&gt;.V3;&lt;/pre&gt;


&lt;p&gt;And that’s it. Just build the solution and run the demo service. If you request the product with ID 0 with URL like http://service/DemoDSPDataService.svc/Products(0) in your browser you should see this property in the output:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;d:Tags &lt;/span&gt;&lt;span style="color: red"&gt;m:type&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;Bag(Edm.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;d:element&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;Bakery&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;d:element&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
    &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;d:element&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;Food&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;d:element&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;d:Tags&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&lt;/span&gt;&lt;/pre&gt;


&lt;p&gt;This is an XML representation of a Multi-Value of primitive type, the JSON representation is similar and uses JSON array to represent it.&lt;/p&gt;

&lt;p&gt;Adding a Multi-Value of complex types is similar to the primitive types, just remember that the T in IEnumerable&amp;lt;T&amp;gt; is the instance type of the complex type, so in this sample provider it would be the DSPResource type.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10088088" width="1" height="1"&gt;</content><author><name>Vitek Karas - MSFT</name><uri>http://blogs.msdn.com/vitkaras/ProfileUrlRedirect.ashx</uri></author></entry><entry><title>Data Services Expressions – Part 9 – Expansions</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/vitek/archive/2010/07/15/data-services-expressions-part-9-expansions.aspx" /><id>http://blogs.msdn.com/b/vitek/archive/2010/07/15/data-services-expressions-part-9-expansions.aspx</id><published>2010-07-15T12:09:33Z</published><updated>2010-07-15T12:09:33Z</updated><content type="html">&lt;p&gt;&lt;font color="#666666"&gt;Series: This post is the ninth part of the &lt;a href="http://blogs.msdn.com/b/vitek/archive/2010/02/25/data-services-expressions-part-1-intro.aspx"&gt;Data Services Expressions Series&lt;/a&gt;&lt;/font&gt;&lt;font color="#666666"&gt;&lt;/font&gt;&lt;font color="#666666"&gt; which describes expressions generated by WCF Data Services.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#000000"&gt;In the last &lt;a href="http://blogs.msdn.com/b/vitek/archive/2010/07/07/data-services-expressions-part-8-projections.aspx"&gt;post&lt;/a&gt; we looked at projections, which leaves us with just one last big feature, expansions.&lt;/font&gt;&lt;/p&gt;  &lt;h3&gt;&lt;font color="#000000"&gt;The $expand query option&lt;/font&gt;&lt;/h3&gt;  &lt;p&gt;&lt;font color="#000000"&gt;Query which targets a certain entity by default returns just primitive and complex properties of that entity. Navigation properties are only represented as links in the response. Expansions allow clients to ask the server to return the entity or entities referred to by a specified navigation property along with the base entity of the query. For a sample let’s take a look at this query:&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#000000" face="Consolas"&gt;http://host/service.svc/Categories&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#000000"&gt;Such query returns category entities. Each category will contain its ID, Name and other primitive or complex properties in the payload. But the Products navigation property will only be represented in the payload as a link. If the client needs the products for each category as well, it would have to download the feed this link points to for each of the categories. Or it can use expansions and ask the server to include the Products in the response as well, like this:&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://host/service.svc/Categories?$expand=Products"&gt;&lt;font color="#000000" face="Consolas"&gt;http://host/service.svc/Categories?$expand=Products&lt;/font&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#000000"&gt;This query will return the same Categories as the previous one, but the Products navigation property will now also include all the product entities for each category in the response. This feature can be very useful for clients to minimize the number of requests issued against the server.&lt;/font&gt;&lt;/p&gt;  &lt;h3&gt;&lt;font color="#000000"&gt;Expressing expansions in expressions&lt;/font&gt;&lt;/h3&gt;  &lt;p&gt;&lt;font color="#000000"&gt;Now let’s take a look at how such query is executed on the server. The simplest approach would be to simply assume that the server can ask for the value of the Products property and it would get back the product entities it needs. But this approach would be inefficient and rather complicated to implement for many providers.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#000000"&gt;As an example let’s consider a provider which reads its data from a database. In the database navigation properties are usually stored as foreign keys. A query which returns categories would simply return all the rows from the table with categories. At the time the service would ask for all products for a given category the provider would have to issue a new query against the database to get such data (from different tables). And this would be repeated for each category in the results. This could quickly become very expensive, not counting that your favorite DBA would not like your application at all.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#000000"&gt;Much better solution would be to ask the provider to get categories and their products in one query so that it could issue a join query. But how to tell the provider that Products are needed as well? We could invent some new way (special method or so), but that would go against the idea that all queries are passed to the provider as LINQ queries.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#000000"&gt;The way this is resolved is by explicitly projecting the navigation property which needs to be expanded. So a simple example of the query above could look something like this:&lt;/font&gt;&lt;/p&gt;  &lt;pre style="font-family: consolas"&gt;categories.Select(category =&amp;gt; &lt;span style="color: blue"&gt;new&lt;/span&gt;&lt;br /&gt;{&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Category = category,&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Products = category.Products&lt;br /&gt;});&lt;br /&gt;&lt;/pre&gt;

&lt;p&gt;&lt;font color="#000000"&gt;You can try this with any existing LINQ provider and it should work as expected, that is retrieve the categories as well as all their products from the data store.&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;font color="#000000"&gt;The above approach can’t be used directly by WCF Data Services. The main problem is that it requires generation of a new type for each set of expanded properties (the return type of the query). So instead a special type is used, which is called ExpandedWrapper. It’s rather similar to the ProjectedWrapper which we discussed in the previous post and it serves very similar purpose.&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;font color="#000000"&gt;ExpandedWrapper is a generic type (in fact there are 12 such types) where the generic parameters specify the type of the entity being expanded and then types of each of the expanded properties. Each ExpandedWrapper then has a property ExpandedElement which will store the entity being expanded (the category in our sample) and a certain number of properties called ProjectedProperty0, ProjectedProperty1 and so on to store the expanded navigation properties. So in our sample above using ExpandedWrapper the query would look like:&lt;/font&gt;&lt;/p&gt;

&lt;pre style="font-family: consolas"&gt;categories.Select(category =&amp;gt; &lt;span style="color: blue"&gt;new&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;ExpandedWrapper&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Category&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Product&lt;/span&gt;&amp;gt;&amp;gt; { &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; ExpandedElement = category, &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Description = &lt;span style="color: #a31515"&gt;&amp;quot;Products&amp;quot;&lt;/span&gt;, &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; ProjectedProperty0 = category.Products &lt;br /&gt;});&lt;/pre&gt;

&lt;p&gt;&lt;font color="#000000"&gt;I didn’t mention the property Description, which servers the same purpose as ProjectedWrapper.PropertyNameList and stores a comma delimited list of names of navigation properties expanded.&lt;/font&gt;&lt;/p&gt;

&lt;h3&gt;&lt;font color="#000000"&gt;The real expression&lt;/font&gt;&lt;/h3&gt;

&lt;p&gt;&lt;font color="#000000"&gt;To be able to look at the real query generated by WCF Data Services our simple reflection based service we used so far won’t do. The reflection provider (which is used if you just provide classes as the service definition) assumes the exact thing we want to avoid. That is being able to access a navigation property any time without any consequences. For in-memory data, this is a very valid assumption as all the data is readily available without a need to issue expensive queries. So the expression generated by the reflection provider for a simple expansion like the one in our sample will not try to tell the LINQ provider to get the expanded properties, since there’s no need. For a custom provider WCF Data Services can’t make such assumption, and so it will generate the expansion expression like shown above.&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;font color="#000000"&gt;So instead of our simple provider we used so far we will use a sample from the OData Provider Toolkit, which you can download here: &lt;a title="http://www.odata.org/developers/odata-sdk" href="http://www.odata.org/developers/odata-sdk"&gt;http://www.odata.org/developers/odata-sdk&lt;/a&gt;. From the downloaded archive extract the Typed\RWNavProp folder and open the solution in it. Add the InterceptingProvider toolkit (as mentioned in our second &lt;a href="http://blogs.msdn.com/b/vitek/archive/2010/03/03/data-services-expressions-part-2-the-query-root.aspx"&gt;post&lt;/a&gt;) to the solution and open the DSPResourceQueryProvider.cs file from the DataServiceProvider project. In it find the method GetTypedQueryRootForResourceSet&amp;lt;TElement&amp;gt; and wrap the call returned IQueryable into the intercepting query, something like this:&lt;/font&gt;&lt;/p&gt;

&lt;pre style="font-family: consolas"&gt;&lt;span style="color: blue"&gt;private&lt;/span&gt; System.Linq.&lt;span style="color: #2b91af"&gt;IQueryable&lt;/span&gt; GetTypedQueryRootForResourceSet&amp;lt;TElement&amp;gt;(&lt;span style="color: #2b91af"&gt;ResourceSet&lt;/span&gt; resourceSet)&lt;br /&gt;{&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;return&lt;/span&gt; Toolkit.&lt;span style="color: #2b91af"&gt;InterceptingProvider&lt;/span&gt;.Intercept(&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;this&lt;/span&gt;.dataSource.GetResourceSetEntities(resourceSet.Name).Cast&amp;lt;TElement&amp;gt;().AsQueryable(),&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; (expression) =&amp;gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&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; System.Diagnostics.&lt;span style="color: #2b91af"&gt;Trace&lt;/span&gt;.WriteLine(expression.ToString());&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; &lt;span style="color: blue"&gt;return&lt;/span&gt; expression;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; });&lt;br /&gt;}&lt;/pre&gt;

&lt;p&gt;&lt;font color="#000000"&gt;Now simply start the ODataDemoService and issue our sample query. You should see an expression like this:&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;font color="#000000" face="Consolas"&gt;System.Linq.Enumerable+&amp;lt;CastIterator&amp;gt;d__b1`1[ODataDemo.CategoryEntity].Select(p =&amp;gt; 
    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;font color="#000000" face="Consolas"&gt;new ExpandedWrapper`2() {
    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ExpandedElement = p, 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Description = &amp;quot;Products&amp;quot;, 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ProjectedProperty0 = p.Products})&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;font color="#000000"&gt;Which is exactly like the one we constructed above, so it works as it should. The above text doesn’t actually show the real type of the ExpandedWrapper, it just shows that it’s a generic type with two parameters (that’s what the `2 means in CLR). The real type if you look at it in the debugger is ExpandedWrapper&amp;lt;CategoryEntity, IEnumerable&amp;lt;ProductEntity&amp;gt;&amp;gt;.&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;font color="#000000"&gt;Note that unlike the ProjectedWrapper expressions, there’s no need for Convert operators in this one since all the properties are strongly typed due to the fact that the ExpandedWrapper is a generic class.&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;font color="#000000"&gt;The p.Products expression above is yet another standard property access expression as described in this &lt;a href="http://blogs.msdn.com/b/vitek/archive/2010/04/16/data-services-expressions-part-4-accessing-properties.aspx"&gt;post&lt;/a&gt;, and as such might differ based on the property definition you use in your provider.&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;font color="#000000"&gt;During serialization WCF Data Services will now recognize the results as being ExpandedWrapper objects, and it will access the ExpandedElement property and use its value as the entity instance. Then when it needs to get the value of the navigation property to expand it will access the right ProjecteProperty property (based on the comma delimited names in the Description property).&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;font color="#000000"&gt;That’s it for a simple expansion. It gets much more complicated if several features are combined together. When both expansions and projections are combined the query will use a combination of ExpandedWrapper and ProjectedWrapper objects and it will get considerably more complex. Also using server driven paging will influence the expression tree a lot. But those are all topics for some future posts.&lt;/font&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10038573" width="1" height="1"&gt;</content><author><name>Vitek Karas - MSFT</name><uri>http://blogs.msdn.com/vitkaras/ProfileUrlRedirect.ashx</uri></author></entry><entry><title>Data Services Expressions – Part 8 – Projections</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/vitek/archive/2010/07/07/data-services-expressions-part-8-projections.aspx" /><id>http://blogs.msdn.com/b/vitek/archive/2010/07/07/data-services-expressions-part-8-projections.aspx</id><published>2010-07-07T15:30:47Z</published><updated>2010-07-07T15:30:47Z</updated><content type="html">&lt;p&gt;&lt;font color="#666666"&gt;&lt;strong&gt;Series:&lt;/strong&gt; This post is the eighth part of the &lt;a href="http://blogs.msdn.com/b/vitek/archive/2010/02/25/data-services-expressions-part-1-intro.aspx"&gt;Data Services Expressions Series&lt;/a&gt; which describes expressions generated by WCF Data Services.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#000000"&gt;Projections feature is visible in the URL through the $select query option. It allows the client to ask the server to only return a subset of properties on the returned entities. In this post we’ll look into how simple projections are handled by the URL parsing and how are these translated into expression executed against the provider.&lt;/font&gt;&lt;/p&gt;  &lt;h3&gt;&lt;font color="#000000"&gt;Properties projected&lt;/font&gt;&lt;/h3&gt;  &lt;p&gt;&lt;font color="#000000"&gt;A simple projection sample in the URL:&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#333333" face="Consolas"&gt;http://host/service.svc/Products?$select=Name&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#000000"&gt;This asks the server to return all product entities, but only include the Name property in the payload. Internally the server will construct a list of properties to request from the data source. So at first the server adds all the properties listed in the $select query option to the list of properties to be projected. For the sample above we have { Name } so far.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#000000"&gt;The client still expects to get back the usual feed of entries (in case of ATOM payload), and for this to work correctly each entity must have a unique identifier in the payload. The WCF Data Services server uses the key properties to construct the identification. So the server will include all key properties in the list of properties to be projected. In our sample above the Product has just one key property called ID, so we have { Name, ID } as the list of properties to project.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#666666"&gt;Note: If ETag is defined for the projected entity, all the ETag properties will be added into the list as well. Also, if there is any EntityPropertyMappingAttribute defined for the projected entity, all the properties mapped by these attributes will be included in the list as well.&lt;/font&gt;&lt;/p&gt;  &lt;h3&gt;&lt;font color="#000000"&gt;ProjectedWrapper&lt;/font&gt;&lt;/h3&gt;  &lt;p&gt;&lt;font color="#000000"&gt;Once we have the complete list of properties we will need for each entity from the data source, we need to define the type of each entity to be returned. This is determined by the LINQ expression we will use to project the properties. Projections are usually expressed through the Select operator like this:&lt;/font&gt;&lt;/p&gt;  &lt;pre style="font-family: consolas"&gt;products.Select(product =&amp;gt; &lt;span style="color: blue"&gt;new&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;Product&lt;/span&gt;()&lt;br /&gt;{&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Name = product.Name,&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; ID = product.ID,&lt;br /&gt;});&lt;/pre&gt;

&lt;p&gt;&lt;font color="#000000"&gt;But this approach doesn’t work if the provider doesn’t use CLR types which reflect the shape of the entity as defined by the provider’s metadata. Some providers use generic CLR types for their entity representation (for example a Dictionary or some other custom object). Accessing properties on such entities uses method calls as described in this &lt;a href="http://blogs.msdn.com/b/vitek/archive/2010/04/16/data-services-expressions-part-4-accessing-properties.aspx"&gt;post&lt;/a&gt;. So instead WCF Data Services uses a special types to project to, the ProjectedWrapper.&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;font color="#000000"&gt;There are in fact ten ProjectedWrapper types. ProjectedWrapper0 to ProjectedWrapper8 are used when 0 to 8 properties need to be projected. ProjectedWrapperMany is used when more then 8 properties are needed, in which case the ProjectedWrapperMany has a Next link to the next ProjectedWrapperMany instance forming a linked list, where each item stores up to eight properties.&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;font color="#000000"&gt;Each ProjectedWrapper type has a property ResourceTypeName which stores the full type name of the entity this projected wrapper represents. This is necessary as it’s not possible to tell the type of the entity based on the few properties projected. We will discuss in detail how type hierarchies are handled in projections in some later post. There’s also another property PropertyNameList on each ProjectedWrapper. This property stores a comma delimited list of names of properties projected into this wrapper.&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;font color="#000000"&gt;The projected properties are then stored in ProjectedWrapper members ProjectedProperty0 to ProjectedProperty7. The first name in the PropertyNameList specifies the name of the property projected into the ProjectedProperty0, the second specifies the name of the ProjectedProperty1 and so on.&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;font color="#000000"&gt;So in our sample above, where we are to project properties Name and ID, using a ProjectedWrapper would look like this:&lt;/font&gt;&lt;/p&gt;

&lt;pre style="font-family: consolas"&gt;products.Select(product =&amp;gt; &lt;span style="color: blue"&gt;new&lt;/span&gt; ProjectedWrapper2() { &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; ResourceTypeName = “TestNamespace.Product”, &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; PropertyNameList = “Name,ID”, &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; ProjectedProperty0 = p.Name, &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; ProjectedProperty1 = p.ID &lt;br /&gt;});&lt;/pre&gt;

&lt;p&gt;&lt;font color="#000000"&gt;As a result the type of the query is now IQueryable&amp;lt;ProjectedWrapper2&amp;gt; (instead of IQueryable&amp;lt;Product&amp;gt; which would be the case without projections). The WCF Data Services will recognize this and will not assume each result to be of the entity type, but instead will use the ProjectedWrapper and the information in it to write the results to the response.&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;font color="#666666"&gt;Note: The reason such a generic looking type like ProjectedWrapper is used instead of something more friendly is performance. Generating new type for each shape of the projection result would be rather expensive.&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;font color="#666666"&gt;Note 2: Currently the data source must return instances of the ProjectedWrapper public type if such type was requested by the query. It is not supported for the provider to change the type of query even if it decides to ignore projections and return the original entity for example. In the future the product might support some looser contract in this place, for example an interface similar to the IExpandedResult.&lt;/font&gt;&lt;/p&gt;

&lt;h3&gt;&lt;font color="#000000"&gt;Projection expression&lt;/font&gt;&lt;/h3&gt;

&lt;p&gt;&lt;font color="#000000"&gt;Knowing about ProjectedWrappers we can finally look at the expression generated by WCF Data Services. Let’s take our sample query from above, the expression generated would look like this:&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;font color="#000000" face="Consolas"&gt;System.Collections.Generic.List`1[DataServiceExpression.Product] 
    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; .Select(p =&amp;gt; IIF((p == null), null, new ProjectedWrapper2() { 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ResourceTypeName = &amp;quot;TestNamespace.Product&amp;quot;, 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; PropertyNameList = &amp;quot;Name,ID&amp;quot;, 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ProjectedProperty0 = Convert((p As Product).Name), 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ProjectedProperty1 = Convert(Convert((p As Product).ID))}))&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;font color="#000000"&gt;This is pretty close to what we came up with above. The first difference is the null check (the IIF((p == null), null, …)). This is so called “null propagation” and in detail I will discuss it at some later time. In short it makes sure that if the result being projected is null, the expression would still work and would project a null and wouldn’t crash. This part of the query can be influenced by modifying the value returned from IDataServiceQueryProvider.IsNullPropagationRequired, assuming you implement a custom provider. I will describe this in more detail in some later post.&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;font color="#000000"&gt;The second difference is the type cast operation “p As Product”. This is needed when there’s type inheritance involved. In the simple case where there’s just one type of entity they are pretty much redundant as the parameter p is already of type Product anyway.&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;font color="#000000"&gt;The third difference is the Convert operator. There are actually two types of these. The outer ones which are present on each property regardless of its type are conversions to System.Object. This is necessary since the ProjectedProperty0 is defined as having System.Object type, and thus the value assigned to it needs to be converted to such type. Note that in most programming languages the compiler will generated this conversion for you automatically, so you don’t usually see this in your code. The second type of Convert operators, the inner one, is only needed on value types and it converts the value to a nullable version of such type. So in the case above it converts the System.Int32 type of the ID property to a Nullable&amp;lt;System.Int32&amp;gt; type. This is again necessary when there’s type inheritance involved, in this simple case the value of the property will never be null.&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;font color="#000000"&gt;So to makes all of the above more clear, here’s the same expression as above rewritten to what it would look like in C#:&lt;/font&gt;&lt;/p&gt;

&lt;pre style="font-family: consolas"&gt;products.Select(p =&amp;gt; (p == &lt;span style="color: blue"&gt;null&lt;/span&gt;) ? &lt;span style="color: blue"&gt;null&lt;/span&gt; : &lt;span style="color: blue"&gt;new&lt;/span&gt; ProjectedWrapper2() { &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; ResourceTypeName = “TestNamespace.Product”, &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; ProductNameList = “Name,ID”, &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; ProjectedProperty0 = (&lt;span style="color: blue"&gt;object&lt;/span&gt;)((p &lt;span style="color: blue"&gt;as&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;Product&lt;/span&gt;).Name), &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; ProjectedProperty1 = (&lt;span style="color: blue"&gt;object&lt;/span&gt;)(&lt;span style="color: blue"&gt;int&lt;/span&gt;?)((p &lt;span style="color: blue"&gt;as&lt;/span&gt;&amp;#160;&lt;span style="color: #2b91af"&gt;Product&lt;/span&gt;).ID) &lt;br /&gt;});&lt;/pre&gt;

&lt;p&gt;&lt;font color="#000000"&gt;And that’s all. We covered all the basics you might need to understand simple projection queries. As noted above it gets more complicated when type inheritance is involved. Also null propagation has some effects on the expressions generated in certain cases. Yet another interesting topic is expansions and their interaction with projections. But I will get to those in some later post.&lt;/font&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10035449" width="1" height="1"&gt;</content><author><name>Vitek Karas - MSFT</name><uri>http://blogs.msdn.com/vitkaras/ProfileUrlRedirect.ashx</uri></author><category term="Data Services" scheme="http://blogs.msdn.com/b/vitek/archive/tags/Data+Services/" /><category term="Data Services Expressions" scheme="http://blogs.msdn.com/b/vitek/archive/tags/Data+Services+Expressions/" /><category term="Data Service Provider" scheme="http://blogs.msdn.com/b/vitek/archive/tags/Data+Service+Provider/" /></entry><entry><title>Data Services Expressions – Part 7 – Navigation</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/vitek/archive/2010/06/22/data-services-expressions-part-7-navigation.aspx" /><id>http://blogs.msdn.com/b/vitek/archive/2010/06/22/data-services-expressions-part-7-navigation.aspx</id><published>2010-06-22T15:39:20Z</published><updated>2010-06-22T15:39:20Z</updated><content type="html">&lt;p&gt;&lt;font color="#666666"&gt;&lt;strong&gt;Series:&lt;/strong&gt; This post is the seventh part of the &lt;a href="http://blogs.msdn.com/b/vitek/archive/2010/02/25/data-services-expressions-part-1-intro.aspx"&gt;Data Services Expressions Series&lt;/a&gt; which describes expressions generated by WCF Data Services.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#000000"&gt;In this post we will examine how navigations are expressed by the WCF Data Services and what the provider needs to do to correctly support them.&lt;/font&gt;&lt;/p&gt;  &lt;h2&gt;&lt;font color="#000000"&gt;What is navigation&lt;/font&gt;&lt;/h2&gt;  &lt;p&gt;&lt;font color="#000000"&gt;In the OData model, entities can have so called “navigation” properties. These properties are references to other entities in the model. There are two types of navigation properties. Resource reference property references a single resource (entity) and can have a null value. Resource reference property has cardinality of 0..1. Resource set reference property references a collection of entities, must not be null but can evaluate to an empty collection. Resource set reference property has cardinality 0..N.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#000000"&gt;In the URL, navigations are expressed as traversal of the specified property in the path. For samples in this post we will use the Product entity we have from previous posts. A class-like description of the entities is here:&lt;/font&gt;&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;public class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Product
&lt;/span&gt;{
    &lt;span style="color: blue"&gt;public int &lt;/span&gt;ID { &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 string &lt;/span&gt;Name { &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 string &lt;/span&gt;Description { &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 double &lt;/span&gt;Price { &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;DateTime &lt;/span&gt;ReleaseDate { &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;DateTime&lt;/span&gt;? DiscontinueDate { &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 int &lt;/span&gt;Rating { &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;Category &lt;/span&gt;Category { &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 class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Category
&lt;/span&gt;{
    &lt;span style="color: blue"&gt;public int &lt;/span&gt;ID { &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 string &lt;/span&gt;Name { &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;List&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Product&lt;/span&gt;&amp;gt; Products { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }
}&lt;/pre&gt;
&lt;font color="#000000"&gt;&lt;/font&gt;

&lt;p&gt;&lt;font color="#000000"&gt;We added a resource reference property (0..1) Category on the Product and then a resource set reference property (0..N) Products on Category. So a sample query with navigation is for example:&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;font color="#000000"&gt;http://host/service.svc/Products(1)/Category&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;font color="#000000"&gt;This query returns the Category for Product with ID 1. The other way round navigation like this:&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;font color="#000000"&gt;http://host/services.svc/Categories(1)/Products&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;font color="#000000"&gt;returns all products which belong to category with ID 1. Navigations can be chained (just like directory traversal), but it is only possible to navigate on properties of a single result. So right after a navigation over resource reference property, we can put another navigation like this:&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;font color="#000000"&gt;http://host/services.svc/Products(1)/Category/Products&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;font color="#000000"&gt;But if the navigation is over a resource set reference property a key lookup must be inserted to specify which entity to use and then another navigation can be used, like this:&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;font color="#000000"&gt;http://host/services.svc/Categories(1)/Products(2)/Category&lt;/font&gt;&lt;/p&gt;

&lt;h2&gt;&lt;font color="#000000"&gt;Resource reference property navigation&lt;/font&gt;&lt;/h2&gt;

&lt;p&gt;&lt;font color="#000000"&gt;Navigating over a resource reference property means to traverse from one entity instance to another over the navigation property. As we’ve discussed in the key lookup description &lt;a href="http://blogs.msdn.com/b/vitek/archive/2010/06/16/data-services-expressions-part-6-key-lookup.aspx"&gt;post&lt;/a&gt;, a single entity is expressed by appending a call to Where method which filters based on the key properties to the query root. So in order to navigate over a resource reference property, we need to project the value of the navigation property on the entity in question. Since the query is constructed to return multiple results (even though it never will), the projection needs to be done through a call to the Select method. So a query for /Products(1)/Category will look like:&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;font color="#000000"&gt;System.Collections.Generic.List`1[TypedService.Product]
    &lt;br /&gt;&amp;#160; &lt;/font&gt;&lt;font color="#000000"&gt;.Where(element =&amp;gt; (element.ID == 1))
    &lt;br /&gt;&amp;#160; .Select(element =&amp;gt; element.Category)&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;font color="#000000"&gt;Note that the body of the Select method is a property access to the resource reference property Category. This property access follows all the same rules as other property accesses, as described in this &lt;a href="http://blogs.msdn.com/b/vitek/archive/2010/04/16/data-services-expressions-part-4-accessing-properties.aspx"&gt;post&lt;/a&gt;. The Select method is in fact an extension method on the class Queryable. It takes two parameters, the implicit IQueryable&amp;lt;Product&amp;gt; which is the source query to project from and a lambda expression which for each Product returns the respective Category entity. All of this can be seen in the detailed view of the expression:&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;font color="#000000"&gt;.Call System.Linq.Queryable.Select(
    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; .Call System.Linq.Queryable.Where(

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .Constant&amp;lt;System.Linq.EnumerableQuery`1[TypedService.Product]&amp;gt;(System.Collections.Generic.List`1[TypedService.Product]),

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; '(.Lambda #Lambda1&amp;lt;System.Func`2[TypedService.Product,System.Boolean]&amp;gt;)),

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; '(.Lambda #Lambda2&amp;lt;System.Func`2[TypedService.Product,TypedService.Category]&amp;gt;))&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;font color="#000000"&gt;.Lambda #Lambda1&amp;lt;System.Func`2[TypedService.Product,System.Boolean]&amp;gt;(TypedService.Product $element) {
    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; $element.ID == 1

    &lt;br /&gt;}&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;font color="#000000"&gt;.Lambda #Lambda2&amp;lt;System.Func`2[TypedService.Product,TypedService.Category]&amp;gt;(TypedService.Product $element) {
    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; $element.Category

    &lt;br /&gt;}&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;font color="#000000"&gt;The provider is expected to return enumeration of Category entities from such query with a single result. If the above query returns no result or more than one result, the WCF Data Services will fail to process the request (with 500 status code). The single instance returned can be null though (the case where product has no category), in which case the response for such query will be 404 Resource Not Found. The 404 status code is the equivalent of null in the HTTP/URL world.&lt;/font&gt;&lt;/p&gt;

&lt;h2&gt;&lt;font color="#000000"&gt;Resource set reference property navigation&lt;/font&gt;&lt;/h2&gt;

&lt;p&gt;&lt;font color="#000000"&gt;Navigating over a resource set reference property is similar in that it must start on a single entity instance. But it returns a collection of entities as its result. Since the expression tree for the single entity is in fact an enumeration, the way to return another set of results is to perform a join. Join queries are expressed by a call to method SelectMany. So a query for /Categories(1)/Products will look like:&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;font color="#000000"&gt;System.Collections.Generic.List`1[TypedService.Category]
    &lt;br /&gt;&amp;#160; .Where(element =&amp;gt; (element.ID == 1))

    &lt;br /&gt;&amp;#160; .SelectMany(element =&amp;gt; Convert(element.Products))&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;font color="#000000"&gt;The SelectMany is again in fact an extension method on class Queryable. It takes two parameters, the first implicit one is the source query and the second is a lambda which takes the category entity and returns an enumeration of products. The result of the SelectMany call is enumeration of products, which is a concatenation of all the enumerations of products returned for all the categories in the source query. &lt;/font&gt;&lt;font color="#000000"&gt;In our case the source query will always return exactly one result, so the result of the whole query is a list of products which belong to the category of ID 1.&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;font color="#000000"&gt;Note that the Convert expression in the lambda converts the value of Products (which in our case is of type List&amp;lt;Product&amp;gt;) to the instance type of the navigation property which in case of resource set reference property is always IEnumerable&amp;lt;T&amp;gt;. In this particular case it is IEnumerable&amp;lt;Product&amp;gt;. Again this is in fact a property access expression.&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;font color="#000000"&gt;For completeness here is the detailed view of the query:&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;font color="#000000"&gt;.Call System.Linq.Queryable.SelectMany(
    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; .Call System.Linq.Queryable.Where(

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .Constant&amp;lt;System.Linq.EnumerableQuery`1[TypedService.Category]&amp;gt;(System.Collections.Generic.List`1[TypedService.Category]),

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; '(.Lambda #Lambda1&amp;lt;System.Func`2[TypedService.Category,System.Boolean]&amp;gt;)),

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; '(.Lambda #Lambda2&amp;lt;System.Func`2[TypedService.Category,System.Collections.Generic.IEnumerable`1[TypedService.Product]]&amp;gt;))&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;font color="#000000"&gt;.Lambda #Lambda1&amp;lt;System.Func`2[TypedService.Category,System.Boolean]&amp;gt;(TypedService.Category $element) {
    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; $element.ID == 1

    &lt;br /&gt;}&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;font color="#000000"&gt;.Lambda #Lambda2&amp;lt;System.Func`2[TypedService.Category,System.Collections.Generic.IEnumerable`1[TypedService.Product]]&amp;gt;(TypedService.Category $element)
    &lt;br /&gt;{

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; (System.Collections.Generic.IEnumerable`1[TypedService.Product])$element.Products

    &lt;br /&gt;}&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;font color="#000000"&gt;A result of such query is expected to return enumeration of Product entities. Such enumeration can be empty or can contain multiple results.&lt;/font&gt;&lt;/p&gt;

&lt;h2&gt;&lt;font color="#000000"&gt;Multiple navigations&lt;/font&gt;&lt;/h2&gt;

&lt;p&gt;&lt;font color="#000000"&gt;Navigations can be chained and the expression generated for these operations are quite predictable. They are basically also results of chaining the single navigations together. So instead of describing again all the details, an example is much easier to understand. A URL query like /Products(1)/Category/Products yields an expression:&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;font color="#000000"&gt;System.Collections.Generic.List`1[TypedService.Product]
    &lt;br /&gt;&amp;#160; .Where(element =&amp;gt; (element.ID == 1))

    &lt;br /&gt;&amp;#160; .Select(element =&amp;gt; element.Category)

    &lt;br /&gt;&amp;#160; .SelectMany(element =&amp;gt; Convert(element.Products))&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;font color="#000000"&gt;In this case since the first navigation is over resource reference property, the second navigation immediately follows the first one. And the second example with key lookup in the middle with URL query like /Categories(1)/Products(2)/Category yields an expression:&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;font color="#000000"&gt;System.Collections.Generic.List`1[TypedService.Category]
    &lt;br /&gt;&amp;#160; .Where(element =&amp;gt; (element.ID == 1))

    &lt;br /&gt;&amp;#160; .SelectMany(element =&amp;gt; Convert(element.Products))

    &lt;br /&gt;&amp;#160; .Where(element =&amp;gt; (element.ID == 2))

    &lt;br /&gt;&amp;#160; .Select(element =&amp;gt; element.Category)&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;font color="#000000"&gt;Here since the first navigation is over a resource set reference property, it must be followed by a key lookup (a filter expressed by a call to Where method) which then can be followed by the second navigation.&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;font color="#000000"&gt;And that’s all there is to navigations. Since the queries in the URL can compose navigations with other operations like sorting, the expression tree generated may also contain such parts. The important thing to remember is that all the query options are applied to the end result of all the navigations.&lt;/font&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10028547" width="1" height="1"&gt;</content><author><name>Vitek Karas - MSFT</name><uri>http://blogs.msdn.com/vitkaras/ProfileUrlRedirect.ashx</uri></author><category term="Data Services" scheme="http://blogs.msdn.com/b/vitek/archive/tags/Data+Services/" /><category term="Data Services Expressions" scheme="http://blogs.msdn.com/b/vitek/archive/tags/Data+Services+Expressions/" /><category term="Data Service Provider" scheme="http://blogs.msdn.com/b/vitek/archive/tags/Data+Service+Provider/" /></entry><entry><title>Data Services Expressions – Part 6 – Key lookup</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/vitek/archive/2010/06/16/data-services-expressions-part-6-key-lookup.aspx" /><id>http://blogs.msdn.com/b/vitek/archive/2010/06/16/data-services-expressions-part-6-key-lookup.aspx</id><published>2010-06-16T20:21:39Z</published><updated>2010-06-16T20:21:39Z</updated><content type="html">&lt;p&gt;&lt;font color="#666666"&gt;&lt;strong&gt;Series:&lt;/strong&gt; This post is the sixth part of the &lt;a href="http://blogs.msdn.com/b/vitek/archive/2010/02/25/data-services-expressions-part-1-intro.aspx"&gt;Data Services Expressions Series&lt;/a&gt; which describes expressions generated by WCF Data Services.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;We will be looking into navigations in the next couple of posts. To be able to do that we first have to explain so called key lookups. With a query to a given entity set, the service returns all the entities in that set. We can use filters and such to limit the entities returned, but such queries will always assume that the result may contain multiple items.&lt;/p&gt;  &lt;p&gt;In order to specify a single entity, the query must somehow identify just one instance. In WCF Data Services each entity has key properties, which serve this purpose. By specifying values for all of the key properties, any given entity instance is uniquely identified. Key lookup is a query (or part of query) which specifies the values for the key properties. So using key lookup we can ask for just one entity. Simple key lookup is like this:&lt;/p&gt;  &lt;p&gt;http://host/service.svc/Products(1)&lt;/p&gt;  &lt;p&gt;The above query returns a single entity or 404 response if the product specified doesn’t exist. Our Product entity has just one key property called ID and thus it’s not necessary to specify the name of the key property. The query above asks for product with its key property (ID) of value 1 (integer).&lt;/p&gt;  &lt;p&gt;When such query is processed and translated into expression tree WCF Data Services will actually generate a query which asks for all products with ID equal to 1. Once that query returns its results, the service will verify that only one result was returned. So the above URL gets translated into expression tree like this one:&lt;/p&gt;  &lt;p&gt;System.Collections.Generic.List`1[TypedService.Product].Where(element =&amp;gt; (element.ID == 1))&lt;/p&gt;  &lt;p&gt;It is pretty straightforward, it’s the query root followed by a filter which picks only products with ID equal to 1.&lt;/p&gt;  &lt;p&gt;Note that we would get the exact same expression by running a URL query like:&lt;/p&gt;  &lt;p&gt;http://host/service.svc/Products?$filter=ID eq 1&lt;/p&gt;  &lt;p&gt;But the response for this query is different, it returns a list with a single item instead of the item itself directly.&lt;/p&gt;  &lt;p&gt;Now let’s see what happens if the given entity has more than one key property. We will use an entity called Record which has two key properties; PartitionID which is an integer and RowID which is a string. A query for a single record looks like this:&lt;/p&gt;  &lt;p&gt;http://host/service.svc/Records(PartitionID=1,RowID=’id0’)&lt;/p&gt;  &lt;p&gt;The expression tree which is generated for this query is a bit different than what we could expect. WCF Data Services will use a separate Where call for each key property it needs to filter the results on, so it looks like this:&lt;/p&gt;  &lt;p&gt;System.Collections.Generic.List`1[TypedService.Record]    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; .Where(element =&amp;gt; (element.PartitionID == 1))     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; .Where(element =&amp;gt; (element.RowID == &amp;quot;id0&amp;quot;))&lt;/p&gt;  &lt;p&gt;Note again that it is expected that such query returns at most one result. If that’s not true the service will fail with a 500 status code.&lt;/p&gt;  &lt;p&gt;And that’s it, key lookups are really not complicated. In the next post we will look at our first navigations over navigation properties.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10026078" width="1" height="1"&gt;</content><author><name>Vitek Karas - MSFT</name><uri>http://blogs.msdn.com/vitkaras/ProfileUrlRedirect.ashx</uri></author><category term="Data Services" scheme="http://blogs.msdn.com/b/vitek/archive/tags/Data+Services/" /><category term="Data Services Expressions" scheme="http://blogs.msdn.com/b/vitek/archive/tags/Data+Services+Expressions/" /><category term="Data Service Provider" scheme="http://blogs.msdn.com/b/vitek/archive/tags/Data+Service+Provider/" /></entry><entry><title>Data Services Expressions – Part 5 – Sorting</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/vitek/archive/2010/06/04/data-services-expressions-part-5-accessing-properties.aspx" /><id>http://blogs.msdn.com/b/vitek/archive/2010/06/04/data-services-expressions-part-5-accessing-properties.aspx</id><published>2010-06-04T13:00:23Z</published><updated>2010-06-04T13:00:23Z</updated><content type="html">&lt;p&gt;&lt;font color="#666666"&gt;&lt;strong&gt;Series:&lt;/strong&gt; This post is the fifth part of the &lt;a href="http://blogs.msdn.com/vitek/archive/2010/02/25/data-services-expressions-part-1-intro.aspx"&gt;Data Services Expressions Series&lt;/a&gt; which describes expressions generated by WCF Data Services.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;This time we will look at how WCF Data Services translates sorting expressions. Sorting expression are used when the URL uses a query option $orderby.&lt;/p&gt;  &lt;h3&gt;Simple sorting&lt;/h3&gt;  &lt;p&gt;In the expression trees, sorting is expressed by a call to the OrderBy method. In the case of WCF Data Services, since the query is expressed as IQueryable, the exact method is System.Linq.Queryable.OrderBy extension method. First parameter of this method is the implicit IQueryable and the second parameter is a lambda expression which returns the value according to which the results should be sorted.&lt;/p&gt;  &lt;p&gt;Let’s take a sample query like:&lt;/p&gt;  &lt;p&gt;http://host/service.svc/Products?$orderby=Price&lt;/p&gt;  &lt;p&gt;WCF Data Services will translate this into an expression like:&lt;/p&gt;  &lt;p&gt;System.Collections.Generic.List`1[TypedService.Product]    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; .OrderBy(element =&amp;gt; element.Price)&lt;/p&gt;  &lt;p&gt;So it’s a query root (see &lt;a href="http://blogs.msdn.com/b/vitek/archive/2010/03/03/data-services-expressions-part-2-the-query-root.aspx"&gt;this&lt;/a&gt; blog post for details) followed by a call to the OrderBy with a lambda which takes the product and extracts its Price property. Note that for sorting expressions WCF Data Services uses the name “element” as the name of parameter expression for the lambda expression.&lt;/p&gt;  &lt;p&gt;The lambda body in this case is a simple property access and as such it will follow all the rules described in my &lt;a href="http://blogs.msdn.com/b/vitek/archive/2010/04/16/data-services-expressions-part-4-accessing-properties.aspx"&gt;previous post&lt;/a&gt; about accessing properties.&lt;/p&gt;  &lt;h3&gt;More complex sorting expression&lt;/h3&gt;  &lt;p&gt;That was a really simple sample, but in reality it usually gets more complicated. WCF Data Services allows usage of expressions in the $orderby query options. So we can use for example arithmetic like in this query:&lt;/p&gt;  &lt;p&gt;http://host/services.svc/Products?$orderby=5 sub Rating&lt;/p&gt;  &lt;p&gt;The expression generated looks like this:&lt;/p&gt;  &lt;p&gt;System.Collections.Generic.List`1[TypedService.Product]    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; .OrderBy(element =&amp;gt; (5 - element.Rating))&lt;/p&gt;  &lt;p&gt;It can obviously get even more complicated, but the expression tree generated would just follow along, without any real surprises.&lt;/p&gt;  &lt;h3&gt;Multiple sorting expressions&lt;/h3&gt;  &lt;p&gt;If we want to specify that the results should be sorted according to multiple sorting expressions, in the query we add more expressions into the $orderby query option and separate them using comma characters. So for example:&lt;/p&gt;  &lt;p&gt;http://host/services.svc/Products?$orderby=Rating,Price&lt;/p&gt;  &lt;p&gt;Unfortunately the OrderBy method which is called in the expression tree to perform the sorting only takes one lambda expression. So to express more sorting expressions another method called ThenBy is used. As with OrderBy the ThenBy in our case is in fact System.Linq.Queryable.ThenBy extension method and it looks exactly the same as OrderBy.&lt;/p&gt;  &lt;p&gt;The expression tree for the above query will look like:&lt;/p&gt;  &lt;p&gt;System.Collections.Generic.List`1[TypedService.Product]    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; .OrderBy(element =&amp;gt; element.Rating)     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; .ThenBy(element =&amp;gt; element.Price)&lt;/p&gt;  &lt;p&gt;Note that if there’s more sorting expressions, other ThenBy calls would be simple appended to the expression tree here. As a result a single $orderby query option will be translated as a call to OrderBy method followed by possibly multiple calls to ThenBy method.&lt;/p&gt;  &lt;h3&gt;Ascending or Descending&lt;/h3&gt;  &lt;p&gt;WCF Data Services also allows us to specify the sorting direction. By default sorting is done in the ascending order (that is 1, 2, 3, …), we can change that to the descending order by adding the keyword “desc” to the sorting expression:&lt;/p&gt;  &lt;p&gt;http://host/services.svc/Products?$orderby=Rating desc&lt;/p&gt;  &lt;p&gt;In the expression tree the change of sorting direction is expressed by calling yet another method OrderByDescending. Other than its name everything else about this method is the same as for the OrderBy method. So the expression tree looks like:&lt;/p&gt;  &lt;p&gt;System.Collections.Generic.List`1[TypedService.Product]    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; .OrderByDescending(element =&amp;gt; element.Rating)&lt;/p&gt;  &lt;p&gt;There’s also a ThenByDescending which is used when more sorting options are specified some of which use the descending order. Again ThenByDescending is exactly the same as ThenBy, except for its name.&lt;/p&gt;  &lt;p&gt;And to show it all of, let’s take our ultimate sorting example:&lt;/p&gt;  &lt;p&gt;http://host/services.svc/Products?$orderby=Rating desc,Price,ReleaseDate desc&lt;/p&gt;  &lt;p&gt;The expression tree generated is this:&lt;/p&gt;  &lt;p&gt;System.Collections.Generic.List`1[TypedService.Product]    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; .OrderByDescending(element =&amp;gt; element.Rating)     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; .ThenBy(element =&amp;gt; element.Price)     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; .ThenByDescending(element =&amp;gt; element.ReleaseDate)&lt;/p&gt;  &lt;p&gt;The last note for this blog post is about the OrderBy, ThenBy, OrderByDescending and ThenByDescending methods. These methods are defined as returning an IOrderedQueryable interface and so if you’re writing your own query provider be sure to support it correctly as described &lt;a href="http://msdn.microsoft.com/en-us/library/bb340178.aspx"&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10019997" width="1" height="1"&gt;</content><author><name>Vitek Karas - MSFT</name><uri>http://blogs.msdn.com/vitkaras/ProfileUrlRedirect.ashx</uri></author><category term="Data Services" scheme="http://blogs.msdn.com/b/vitek/archive/tags/Data+Services/" /><category term="Data Services Expressions" scheme="http://blogs.msdn.com/b/vitek/archive/tags/Data+Services+Expressions/" /><category term="Data Service Provider" scheme="http://blogs.msdn.com/b/vitek/archive/tags/Data+Service+Provider/" /></entry><entry><title>Data Services Expressions – Part 4 – Accessing properties</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/vitek/archive/2010/04/16/data-services-expressions-part-4-accessing-properties.aspx" /><id>http://blogs.msdn.com/b/vitek/archive/2010/04/16/data-services-expressions-part-4-accessing-properties.aspx</id><published>2010-04-16T11:24:00Z</published><updated>2010-04-16T11:24:00Z</updated><content type="html">&lt;p&gt;&lt;font color="#666666"&gt;&lt;strong&gt;Series:&lt;/strong&gt; This post is the fourth part of the &lt;a href="http://blogs.msdn.com/vitek/archive/2010/02/25/data-services-expressions-part-1-intro.aspx"&gt;Data Services Expressions Series&lt;/a&gt; which describes expressions generated by WCF Data Services.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;In this part we will talk about accessing properties in the expressions. WCF Data Services may need to access a property value in many different places in the query, but it always uses the same way to do so. Below I’ll use the $filter as an example, but the same would apply to any other place in the query (for example $orderby, $select and so on).&lt;/p&gt;  &lt;h3&gt;Property metadata&lt;/h3&gt;  &lt;p&gt;In the WCF Data Services world the shape of the data is defined using metadata classes like &lt;a href="http://msdn.microsoft.com/en-us/library/system.data.services.providers.resourcetype(VS.100).aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.data.services.providers.resourcetype(VS.100).aspx"&gt;ResourceType&lt;/a&gt; and &lt;a href="http://msdn.microsoft.com/en-us/library/system.data.services.providers.resourceproperty(v=VS.100).aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.data.services.providers.resourceproperty(v=VS.100).aspx"&gt;ResourceProperty&lt;/a&gt;. To get a general idea how to do that, take a look at this &lt;a href="http://blogs.msdn.com/alexj/archive/2010/01/07/data-service-providers-getting-started.aspx" mce_href="http://blogs.msdn.com/alexj/archive/2010/01/07/data-service-providers-getting-started.aspx"&gt;series&lt;/a&gt; by Alex. Note that even if you’re not using a custom provider, underneath both the built-in providers will define the metadata in the same way, so there’s no hidden magic there.&lt;/p&gt;  &lt;p&gt;Currently WCF Data Services uses three kinds of resource types: Entity types, Complex types and Primitive types. Each resource type is defined in the metadata by an instance of ResourceType class.&lt;/p&gt;  &lt;p&gt;Both entity and complex types can define properties. A property can be of any resource type (with some limitations, but that’s for another topic). Each property is defined in the metadata by an instance of the ResourceProperty class.&lt;/p&gt;  &lt;p&gt;The value of a property is either a primitive type, instance of an entity type, instance of a complex type or null. The actual CLR type of the property value is determined (and defined) by the resource type of the property. Each resource type has an instance type which is the CLR type used to store an instance of that resource type. For example a primitive resource type Edm.String, has instance type System.String. For entity and complex types, the instance type is defined by you in the metadata, usually it’s some class.&lt;/p&gt;  &lt;h3&gt;Accessing a property value in an expression&lt;/h3&gt;  &lt;p&gt;We’ll use $filter as a sample of an expression which accesses properties. If you want to know more about the filters please take a look at my previous &lt;a href="http://blogs.msdn.com/vitek/archive/2010/04/15/data-services-expressions-part-3-filters.aspx" mce_href="http://blogs.msdn.com/vitek/archive/2010/04/15/data-services-expressions-part-3-filters.aspx"&gt;post&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;We’ll use the same sample query here:&lt;/p&gt;  &lt;p&gt;http://host/service.svc/Products?$filter=Rating gt 3&lt;/p&gt;  &lt;p&gt;In the metadata the entity type Product defines a primitive property Rating of type Int32. The filter expression needs to get the value of the Rating property for any given Product and compare it to number 3.&lt;/p&gt;  &lt;p&gt;In a filter expression, which is a lambda expression which takes a parameter called “product” which holds an instance of the Product entity type, such property access would look like:&lt;/p&gt;  &lt;p&gt;product.Rating&lt;/p&gt;  &lt;p&gt;No magic, exactly what you would expect. But …&lt;/p&gt;  &lt;h3&gt;Typed and untyped properties&lt;/h3&gt;  &lt;p&gt;In the metadata definition of a property, which is represented by an instance of a ResourceProperty type, there’s a setting called &lt;a href="http://msdn.microsoft.com/en-us/library/system.data.services.providers.resourceproperty.canreflectoninstancetypeproperty(v=VS.100).aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.data.services.providers.resourceproperty.canreflectoninstancetypeproperty(v=VS.100).aspx"&gt;CanReflectOnInstanceProperty&lt;/a&gt;. By default this value is set to true, which means that WCF Data Services can use normal CLR way of accessing the property value. In short we’ll call these properties “typed” properties meaning they have a backing CLR type which that property defined.&lt;/p&gt;  &lt;p&gt;But if you change this setting to false, it tells WCF Data Services that it must not use the CLR way of accessing such property. For short we’ll call these properties “untyped”, meaning that the CLR type of the resource (entity, complex) doesn’t have such property on it, or it should not be used. Defining a property as untyped gives you full control over how the value of such property is determined for any given resource. But this ability comes with a price, it’s more complicated (more code).&lt;/p&gt;  &lt;h3&gt;Accessing a typed property&lt;/h3&gt;  &lt;p&gt;Let’s assume we’re constructing a filter expression as the sample above and thus we have defined a parameter expression which will have the instance of the Product entity we’re filtering:&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: #2b91af"&gt;ParameterExpression &lt;/span&gt;productParameter = &lt;br /&gt;    &lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt;.Parameter(&lt;span style="color: blue"&gt;typeof&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;Product&lt;/span&gt;), &lt;span style="color: #a31515"&gt;&amp;quot;product&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

&lt;p&gt;Accessing a typed property is simple as we’ve shown above. WCF Data Services uses the normal CLR way of accessing the property. In expression trees this means that accessing a property Rating on our product resource is generated like this:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;rating = &lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt;.Property(productParameter, &lt;span style="color: #a31515"&gt;&amp;quot;Rating&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

&lt;p&gt;Note that this is a shortcut for what actually happens underneath which is:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;rating = &lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt;.MakeMemberAccess(
    productParameter, 
    productParameter.Type.GetProperty(&lt;span style="color: #a31515"&gt;&amp;quot;Rating&amp;quot;&lt;/span&gt;));&lt;/pre&gt;

&lt;p&gt;The result (in either case) is a MemberExpression where Expression is the productParameter and the Member is the CLR PropertyInfo for the Rating property.&lt;/p&gt;

&lt;p&gt;Note that since we’re using reflection to access the property, the CLR type of the property access expression is the same type as the instance type of the Rating CLR property. In our case it’s Itn32.&lt;/p&gt;

&lt;p&gt;This mechanism is used to access any “typed” property, be it a primitive, complex or a reference to a resource (or multiple resources).&lt;/p&gt;

&lt;h3&gt;Accessing an untyped property&lt;/h3&gt;

&lt;p&gt;If we specify CanReflectOnInstanceProperty = false for our Rating property, the expression generated will be completely different. In this case WCF Data Services must not use CLR reflection to access the property and as a result it doesn’t have a typical way to access the value.&lt;/p&gt;

&lt;p&gt;It could use a call to IDataServiceQueryProvider.GetPropertyValue to get the value (as that is the method called to access the property value during serialization for example). But it turns out that it’s not the best way to do so in an expression. The main reason is that such call would require the instance of the IDataServiceQueryProvider to be either specified in the expression as a constant or passed in as a parameter. In either case it complicates the expression and makes it dependant on the actual instance of the IDataServiceQueryProvider. This is not suitable for some providers as they are not always going to use the IDataServiceQueryProvider to access the property value, for example they might translate the entire query into a SQL statement, in which case it doesn’t make sense to have a query provider in there.&lt;/p&gt;

&lt;p&gt;So instead WCF Data Services uses special method calls in the expression as basically a placeholder for saying “I want the value of this property here”. Our sample above would then look like:&lt;/p&gt;

&lt;pre class="code"&gt;(&lt;span style="color: #2b91af"&gt;Int32&lt;/span&gt;)&lt;span style="color: #2b91af"&gt;DataServiceProviderMethods&lt;/span&gt;.GetValue(&lt;br /&gt;    product, &lt;br /&gt;    ratingResourceProperty);&lt;/pre&gt;

&lt;p&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.data.services.providers.dataserviceprovidermethods(v=VS.100).aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.data.services.providers.dataserviceprovidermethods(v=VS.100).aspx"&gt;DataServiceProviderMethods&lt;/a&gt; is a class which holds all these placeholder methods WCF Data Services uses. The &lt;a href="http://msdn.microsoft.com/en-us/library/system.data.services.providers.dataserviceprovidermethods.getvalue(v=VS.100).aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.data.services.providers.dataserviceprovidermethods.getvalue(v=VS.100).aspx"&gt;GetValue&lt;/a&gt; method is used to specify the intent to get a value of a property on a resource. The ratingResourceProperty is the instance of the ResourceProperty class which was used in the metadata to define the Rating property. It identifies the property to access. And the product is an instance of the resource (in our case the Product entity) for which to get the value of a property.&lt;/p&gt;

&lt;p&gt;In expression this will be constructed like this:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;var &lt;/span&gt;rating = &lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt;.Call(
    &lt;span style="color: blue"&gt;typeof&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;DataServiceProviderMethods&lt;/span&gt;).GetMethod(&lt;span style="color: #a31515"&gt;&amp;quot;GetValue&amp;quot;&lt;/span&gt;),
    productParameter,
    &lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt;.Constant(ratingResourceProperty));&lt;/pre&gt;

&lt;p&gt;Note that all the methods on the DataServiceProviderMethods class are static, and that their implementation simply throws a NotImplementedException.&lt;/p&gt;

&lt;p&gt;This forces the custom provider to replace such expression with some custom way of accessing the property. What this means to us is that it’s more work as we need to replace the expression in the tree with something which will actually get the value. But it also gives us great power. We can do really whatever we want to get the value of the property.&lt;/p&gt;

&lt;p&gt;For providers which translate the entire query into a different language (like SQL for example), this provides an easy way to spot the property access in the tree (calls to these special methods are easy to recognize) and it gives them the ResourceProperty instance on which they can store some custom data to help in generating the query.&lt;/p&gt;

&lt;p&gt;But even for providers which will execute the LINQ query eventually like a LINQ query (either using LINQ to Objects or something else), this provides the ability to specify a custom way of getting the property value. Using this mechanism we could for example rename a property, change its type, get its value not from a CLR property but from some property bag (Dictionary) or compute it from something completely different.&lt;/p&gt;

&lt;h3&gt;Untyped property access – the details&lt;/h3&gt;

&lt;p&gt;There are few more details we need to be aware of though.&lt;/p&gt;

&lt;p&gt;First one is that the GetValue method is declared as returning a type System.Object. That alone is not very useful for the expression as it can’t for example be compared to a number. As a result most of the occurrences of GetValue call will be surrounded by a type conversion which casts the object to the actual instance type of the property. So the expression would in fact be constructed by using one more line of code like this:&lt;/p&gt;

&lt;pre class="code"&gt;rating = &lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt;.Convert(&lt;br /&gt;    rating, &lt;br /&gt;    ratingResourceProperty.ResourceType.InstanceType);&lt;/pre&gt;

&lt;p&gt;The Rating property is of a primitive resource type which has an instance type System.Int32.&lt;/p&gt;

&lt;p&gt;The second detail to be aware of is that not all properties are accessed using the GetValue method. Resource set reference properties (properties which represent a one to many relationships) are accessed in a similar fashion through a call to &lt;a href="http://msdn.microsoft.com/en-us/library/ee514811(v=VS.100).aspx" mce_href="http://msdn.microsoft.com/en-us/library/ee514811(v=VS.100).aspx"&gt;GetSequenceValue&lt;/a&gt;. We won’t go into the details of why is it like that, let’s just say that it’s useful since the GetSequenceValue returns IEnumerable&amp;lt;T&amp;gt; which allows for further query composition.&lt;/p&gt;

&lt;p&gt;The last detail is that if the given property is an open property, the way to access its value is completely different and we’re not going to describe it here either as it’s a topic for a much larger post.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9997167" width="1" height="1"&gt;</content><author><name>Vitek Karas - MSFT</name><uri>http://blogs.msdn.com/vitkaras/ProfileUrlRedirect.ashx</uri></author></entry><entry><title>Data Services Expressions – Part 3 – Filters</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/vitek/archive/2010/04/15/data-services-expressions-part-3-filters.aspx" /><id>http://blogs.msdn.com/b/vitek/archive/2010/04/15/data-services-expressions-part-3-filters.aspx</id><published>2010-04-15T12:02:01Z</published><updated>2010-04-15T12:02:01Z</updated><content type="html">&lt;p&gt;&lt;font color="#666666"&gt;&lt;strong&gt;Series:&lt;/strong&gt; This post is the third part of the &lt;a href="http://blogs.msdn.com/vitek/archive/2010/02/25/data-services-expressions-part-1-intro.aspx"&gt;Data Service Expressions Series&lt;/a&gt;&lt;/font&gt;&lt;font color="#666666"&gt; which describes expressions generated by WCF Data Services.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#000000"&gt;In this part we will look at how filters are represented in the expressions.&lt;/font&gt;&lt;/p&gt;  &lt;h3&gt;The Queryable.Where method&lt;/h3&gt;  &lt;p&gt;Filters are meant to filter the entities (rows) returned from a given resource set. The client specifies the filter using the $filter query option in the URL. For example (using the sample service from odata.org):&lt;/p&gt;  &lt;p&gt;&lt;a href="http://services.odata.org/OData/OData.svc/Products?$filter=Rating gt 3"&gt;http://services.odata.org/OData/OData.svc/Products?$filter=Rating gt 3&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;The intention of this query is to evaluate the filter expression (the part after the equal sign) for each product in the Products resource set, convert the result to a boolean and only return those products which return true. So the above query should return only products with rating greater than 3.&lt;/p&gt;  &lt;p&gt;WCF Data Services takes this query and translates it into an expression tree. In expression trees, the way to express filters is to use the Where method. So the query would look like this:&lt;/p&gt;  &lt;pre class="code"&gt;products.Where(product =&amp;gt; product.Rating &amp;gt; 3);&lt;/pre&gt;

&lt;p&gt;This is a nice C# way of writing what in fact looks like this:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: #2b91af"&gt;Queryable&lt;/span&gt;.Where(products, product =&amp;gt; product.Rating &amp;gt; 3);&lt;/pre&gt;

&lt;p&gt;The Queryable.Where is an extension method for IQueryable&amp;lt;T&amp;gt;, so that’s why it can be called on the products as if it was its member method. The other thing is that it’s a generic method which takes the T (the type of one resource) as a generic parameter. So it actually looks like this:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: #2b91af"&gt;Queryable&lt;/span&gt;.Where&amp;lt;&lt;span style="color: #2b91af"&gt;Product&lt;/span&gt;&amp;gt;(products, product =&amp;gt; product.Rating &amp;gt; 3);&lt;/pre&gt;

&lt;p&gt;The first parameter is the IQueryable&amp;lt;T&amp;gt; which returns the resources to filter. The second parameter is the filter expression. It is an instance of &lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Func&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Product&lt;/span&gt;, &lt;span style="color: blue"&gt;bool&lt;/span&gt;&amp;gt;&amp;gt;&lt;/pre&gt;

&lt;p&gt;So it’s an expression which represents a function which takes a single parameter of type Product and returns a boolean. In expression trees functions like this are expressed using lambda expressions.&lt;/p&gt;

&lt;h3&gt;Lambda expressions&lt;/h3&gt;

&lt;p&gt;A lambda expression takes a list of parameters (the parameters of the function) and a lambda body. Just like typical function takes parameters and has some body which computes the result.&lt;/p&gt;

&lt;p&gt;Parameters are simply an array of instances of ParameterExpression expression node. Each such instance represents a parameter (you give it a type and a name).&lt;/p&gt;

&lt;p&gt;The lambda body is an expression tree which can reference these parameters whenever it needs to access the value of the given parameter.&lt;/p&gt;

&lt;p&gt;So the above filter expression is just a nice C# way of writing:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: #2b91af"&gt;ParameterExpression &lt;/span&gt;productParameter = &lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt;.Parameter(&lt;span style="color: blue"&gt;typeof&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;Product&lt;/span&gt;), &lt;span style="color: #a31515"&gt;&amp;quot;product&amp;quot;&lt;/span&gt;);
&lt;span style="color: #2b91af"&gt;Expression &lt;/span&gt;body = &lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt;.GreaterThan(
    &lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt;.Property(productParameter, &lt;span style="color: #a31515"&gt;&amp;quot;Rating&amp;quot;&lt;/span&gt;),
    &lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt;.Constant(3));
&lt;span style="color: blue"&gt;var &lt;/span&gt;lambda = (&lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Func&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Product&lt;/span&gt;, &lt;span style="color: blue"&gt;bool&lt;/span&gt;&amp;gt;&amp;gt;)&lt;span style="color: #2b91af"&gt;Expression&lt;/span&gt;.Lambda(
    body,
    productParameter);&lt;/pre&gt;

&lt;p&gt;For now let’s ignore how exactly the body is constructed and its parts, we’ll talk about these in some later post, instead let’s focus on how the lambda expression itself is used.&lt;/p&gt;

&lt;h3&gt;Filter expressions&lt;/h3&gt;

&lt;p&gt;And now back to our filter, using the way to view expressions generated by WCF Data Services from the previous &lt;a href="http://blogs.msdn.com/vitek/archive/2010/03/03/data-services-expressions-part-2-the-query-root.aspx"&gt;blog post&lt;/a&gt;, let’s take a look at expression generated for our sample query:&lt;/p&gt;

&lt;p&gt;http://host/service.svc/Products?$filter=Rating gt 3&lt;/p&gt;

&lt;p&gt;The expression looks like this (result of the Expression.ToString() method):&lt;/p&gt;

&lt;p&gt;System.Collections.Generic.List`1[TypedService.Product].Where(it =&amp;gt; (it.Rating &amp;gt; 3))&lt;/p&gt;

&lt;p&gt;Note that this is using the nice C# notation in which the Where call is treated as instance method and it shows the filter expression as the C# lambda expression. WCF Data Services calls the parameter expression for the filter expression which holds the resource instance “it”. It’s the same thing as in our samples above where we were using “product”.&lt;/p&gt;

&lt;p&gt;To see the real expression, let’s look at the Expression.DebugView:&lt;/p&gt;

&lt;p&gt;.Call System.Linq.Queryable.Where( 
  &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; .Constant&amp;lt;System.Linq.EnumerableQuery`1[TypedService.Product]&amp;gt;(System.Collections.Generic.List`1[TypedService.Product]), 

  &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; '(.Lambda #Lambda1&amp;lt;System.Func`2[TypedService.Product,System.Boolean]&amp;gt;)) &lt;/p&gt;

&lt;p&gt;.Lambda #Lambda1&amp;lt;System.Func`2[TypedService.Product,System.Boolean]&amp;gt;(TypedService.Product $it) { 
  &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; $it.Rating &amp;gt; 3 

  &lt;br /&gt;}&lt;/p&gt;

&lt;p&gt;Here we can see that the expression is actually a Call to the Queryable.Where method, which takes two parameters. The first parameter is the query root (see the previous &lt;a href="http://blogs.msdn.com/vitek/archive/2010/03/03/data-services-expressions-part-2-the-query-root.aspx"&gt;blog post&lt;/a&gt; for discussion about the query root expressions). The second parameter is the lambda expression called #Lambda1 which represents the filter expression. As you can see above that lambda expression takes one parameter of type Product called $it and its body is $it.Rating &amp;gt; 3.&lt;/p&gt;

&lt;p&gt;This was just the basic structure of how filters are handled by WCF Data Services. In the next post we’ll talk about the filter expression itself and specifically about the part of access property values.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9996460" width="1" height="1"&gt;</content><author><name>Vitek Karas - MSFT</name><uri>http://blogs.msdn.com/vitkaras/ProfileUrlRedirect.ashx</uri></author><category term="Data Services" scheme="http://blogs.msdn.com/b/vitek/archive/tags/Data+Services/" /><category term="Data Services Expressions" scheme="http://blogs.msdn.com/b/vitek/archive/tags/Data+Services+Expressions/" /><category term="Data Service Provider" scheme="http://blogs.msdn.com/b/vitek/archive/tags/Data+Service+Provider/" /></entry><entry><title>Data Services Expressions – Part 2 – The query root</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/vitek/archive/2010/03/03/data-services-expressions-part-2-the-query-root.aspx" /><id>http://blogs.msdn.com/b/vitek/archive/2010/03/03/data-services-expressions-part-2-the-query-root.aspx</id><published>2010-03-03T13:51:04Z</published><updated>2010-03-03T13:51:04Z</updated><content type="html">&lt;p&gt;&lt;font color="#666666"&gt;&lt;strong&gt;Series:&lt;/strong&gt; This post is the second part of the &lt;a href="http://blogs.msdn.com/vitek/archive/2010/02/25/data-services-expressions-part-1-intro.aspx"&gt;Data Services Expressions Series&lt;/a&gt;&lt;/font&gt;&lt;font color="#666666"&gt;&lt;/font&gt;&lt;font color="#666666"&gt; which describes expressions generated by WCF Data Services.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;In this part we will first look how to watch the expressions generated by Data Services. Then we’re going to discuss our first expression, the query root.&lt;/p&gt;  &lt;h3&gt;How to see the expression?&lt;/h3&gt;  &lt;p&gt;To see the expressions generated by Data Services we need to get into the query processing pipeline. To do that, we need to implement IQueryable as that is the only public interface Data Services use to construct and execute all its queries as discussed in the &lt;a href="http://blogs.msdn.com/vitek/archive/2010/02/25/data-services-expressions-part-1-intro.aspx"&gt;Part 1&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Fortunately for me Alex just recently posted a perfect IQueryable implementation for this purpose, the &lt;a href="http://blogs.msdn.com/alexj/archive/2010/03/01/tip-55-how-to-extend-an-iqueryable-by-wrapping-it.aspx"&gt;InterceptedQuery&amp;lt;T&amp;gt; and InterceptingProvider&lt;/a&gt;. So instead of writing one from scratch, let’s just use that one.&lt;/p&gt;  &lt;blockquote&gt;   &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;public &lt;/span&gt;&lt;span style="color: #2b91af"&gt;IQueryable&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af"&gt;Product&lt;/span&gt;&amp;gt; Products
{
    &lt;span style="color: blue"&gt;get
    &lt;/span&gt;{
        &lt;span style="color: blue"&gt;return &lt;/span&gt;Toolkit.&lt;span style="color: #2b91af"&gt;InterceptingProvider&lt;/span&gt;.Intercept(
            products.AsQueryable(),
            (expression) =&amp;gt; {
                &lt;span style="color: #2b91af"&gt;Trace&lt;/span&gt;.WriteLine(expression.ToString()); 
                &lt;span style="color: blue"&gt;return &lt;/span&gt;expression; 
            });
    }
}&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you put this into your sample service, every time you issue a query against the service it will write the expression into the debug output. The simplest way to watch these is to run your service under Visual Studio debugger, the debug output will show up in the Output window.&lt;/p&gt;

&lt;p&gt;For detailed viewing you can put a breakpoint into the above code and inspect the expression from the Watch window.&lt;/p&gt;

&lt;p&gt;And now to our first expression.&lt;/p&gt;

&lt;h3&gt;The query root&lt;/h3&gt;

&lt;p&gt;Each query starts with a resource set. To build a query the Data Services gets the query for the resource set root and then builds on top of it. Data Services calls the IDataServiceQueryProvider.GetQueryRootForResourceSet method to get an instance of IQueryable for the given resource set. Each IQueryable has an expression which can be accessed through the IQueryable.Expression property. The expression which is in the IQueryable returned from the GetQueryRootForResourceSet is called the query root.&lt;/p&gt;

&lt;p&gt;The query root expression is interesting to us, because we get to specify it completely. Data Services will not modify the expression, it will just use it as the starting point. The nice thing about this is that we can use even expression which Data Services would not recognize, we can use our own stuff here.&lt;/p&gt;

&lt;p&gt;There’s only one assumption which Data Services makes about this expression and that is it’s CLR type, which is the value of Expression.Type property. This type must implement IQueryable&amp;lt;T&amp;gt; where T is the instance type of the base resource type of the resource set (ResourceSet.ResourceType.InstanceType). In the above example that would be an IQueryable&amp;lt;Product&amp;gt;.&lt;/p&gt;

&lt;p&gt;In the sample above the query root is the “products” variable, which is an instance of List&amp;lt;Product&amp;gt;. You can see this by watching the expression generated for a query “TypedService.svc/Products”.&lt;/p&gt;
&lt;a href="http://blogs.msdn.com/blogfiles/vitek/WindowsLiveWriter/DataServicesExpressionPart2_457A/ProductsOutput_2.png"&gt;&lt;img style="border-right-width: 0px; margin: 0px 20px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="ProductsOutput" border="0" alt="ProductsOutput" src="http://blogs.msdn.com/blogfiles/vitek/WindowsLiveWriter/DataServicesExpressionPart2_457A/ProductsOutput_thumb_1.png" width="454" height="106" /&gt;&lt;/a&gt; 

&lt;p&gt;It looks like the query root is the List&amp;lt;Product&amp;gt; itself, but it’s not. The actual expression node is a constant expression with the value of IQueryable implementation over the list of products. To see this we’ll take a look in the debugger.&lt;/p&gt;
&lt;a href="http://blogs.msdn.com/blogfiles/vitek/WindowsLiveWriter/DataServicesExpressionPart2_457A/ProductsWatch.png"&gt;&lt;img style="border-right-width: 0px; margin: 0px 20px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="ProductsWatch" border="0" alt="ProductsWatch" src="http://blogs.msdn.com/blogfiles/vitek/WindowsLiveWriter/DataServicesExpressionPart2_457A/ProductsWatch_thumb.png" width="466" height="168" /&gt;&lt;/a&gt; 

&lt;p&gt;We can see that the NodeType of the expression is Constant and the value is the List&amp;lt;Product&amp;gt;. If you’re using Visual Studio 2010 and .NET 4.0 there’s a new property on each Expression called DebugView which returns more detailed text representation of the expression. In this case it returns:&lt;/p&gt;

&lt;pre class="code"&gt;.Constant&amp;lt;System.Linq.EnumerableQuery`1[TypedService.Product]&amp;gt;
    (System.Collections.Generic.List`1[TypedService.Product])&lt;/pre&gt;

&lt;p&gt;This shows us that the Type of the expression is System.Linq.EnumerableQuery&amp;lt;Product&amp;gt; which is the LINQ to Object’s implementation of IQueryable&amp;lt;Product&amp;gt;. So it fulfills the requirement of Data Services to be of type IQueryable&amp;lt;Product&amp;gt;.&lt;/p&gt;

&lt;p&gt;Custom query providers usually return some expression which represents the resource set root. This expression then holds information like the Table to get the data from, or the list of resources and so on.&lt;/p&gt;

&lt;p&gt;In all our future visits to Data Services Expressions we will see this query root expression at the beginning of each query.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9972141" width="1" height="1"&gt;</content><author><name>Vitek Karas - MSFT</name><uri>http://blogs.msdn.com/vitkaras/ProfileUrlRedirect.ashx</uri></author><category term="Data Services" scheme="http://blogs.msdn.com/b/vitek/archive/tags/Data+Services/" /><category term="Data Services Expressions" scheme="http://blogs.msdn.com/b/vitek/archive/tags/Data+Services+Expressions/" /><category term="Data Service Provider" scheme="http://blogs.msdn.com/b/vitek/archive/tags/Data+Service+Provider/" /></entry><entry><title>Data Services Expressions – Part 1 - Intro</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/vitek/archive/2010/02/25/data-services-expressions-part-1-intro.aspx" /><id>http://blogs.msdn.com/b/vitek/archive/2010/02/25/data-services-expressions-part-1-intro.aspx</id><published>2010-02-25T09:28:22Z</published><updated>2010-02-25T09:28:22Z</updated><content type="html">&lt;p&gt;WCF Data Services uses Data Service Providers to determine the shape and actual values of the data to expose. There are two providers implemented already for you (Entity Framework provider and Reflection provider) and you can also implement a custom provider.&lt;/p&gt;  &lt;p&gt;Alex James is writing a &lt;a href="http://blogs.msdn.com/alexj/archive/2010/01/07/data-service-providers-getting-started.aspx"&gt;great series&lt;/a&gt; about how to implement such custom provider. You should read it to understand how the custom provider works.&lt;/p&gt;  &lt;p&gt;Custom Data Service Provider gives you the ability to define the metadata, the update behavior and lot of other extensibility points. The portion I will focus on in this series is the ability to provide custom query provider.&lt;/p&gt;  &lt;p&gt;Whenever Data Services need to query the data source to get some data values, it uses the query provider. The most important method of that provider is the &lt;font face="Courier New"&gt;&lt;strong&gt;IDataServiceQueryProvider.GetQueryRootForResourceSet&lt;/strong&gt;&lt;/font&gt;. This method returns IQueryable which Data Services uses to construct and execute the query.&lt;/p&gt;  &lt;p&gt;There are many descriptions of how to implement IQueryable interface, so I won’t try to produce yet another one. I will just point you to the one written by Matt Warren &lt;a href="http://blogs.msdn.com/mattwar/archive/2007/07/30/linq-building-an-iqueryable-provider-part-i.aspx"&gt;here&lt;/a&gt;. You should read the first few posts of that series to understand the basics of IQueryable and expression trees.&lt;/p&gt;  &lt;p&gt;In short IQueryable is an interface that allows the caller to construct a query and then run it. The caller (in our case Data Services) builds the query by constructing an expression tree which describes the intent of the query.&lt;/p&gt;  &lt;p&gt;Implementing your IQueryable and supporting all the expression trees it can get in full is hard. In fact it’s so hard that I would say there’s only one complete implementation, LINQ to Objects. All other LINQ providers have some limitations. It’s so hard because the space of possible expression trees is infinite and very complex.&lt;/p&gt;  &lt;p&gt;The good news for you, who I hope is trying to implement a Data Service Provider, is that Data Services will use only a very small portion of all possible Expression trees. The goal of this series will be to describe this small portion, so that you can implement your own IQueryable which will support enough expressions for Data Services to work correctly.&lt;/p&gt;  &lt;p&gt;There’s even better news which is that depending on your requirements and features of Data Services you use, you can implement only part of the possible expression trees and still work correctly.&lt;/p&gt;  &lt;p&gt;In this series we will take some portion or feature of the query language Data Services support, for example the $filter query option, and then we’ll describe what type of expression trees Data Services generates to describe the query to the underlying Data Service Provider.&lt;/p&gt;  &lt;p&gt;In the next part we’ll talk about the query root and the expressions used by Data Services to access property values.&lt;/p&gt;  &lt;h3&gt;Data Services Expressions Series&lt;/h3&gt;  &lt;p&gt;This series describes expressions generated by WCF Data Services&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/vitek/archive/2010/02/25/data-services-expressions-part-1-intro.aspx"&gt;Part 1 – Intro&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/vitek/archive/2010/03/03/data-services-expressions-part-2-the-query-root.aspx"&gt;Part 2 – The query root&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/vitek/archive/2010/04/15/data-services-expressions-part-3-filters.aspx"&gt;Part 3 – Filters&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/vitek/archive/2010/04/16/data-services-expressions-part-4-accessing-properties.aspx"&gt;Part 4 – Accessing properties&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/b/vitek/archive/2010/06/04/data-services-expressions-part-5-accessing-properties.aspx"&gt;Part 5 – Sorting&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/b/vitek/archive/2010/06/16/data-services-expressions-part-6-key-lookup.aspx"&gt;Part 6 – Key lookups&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/b/vitek/archive/2010/06/22/data-services-expressions-part-7-navigation.aspx"&gt;Part 7 – Navigation&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/b/vitek/archive/2010/07/07/data-services-expressions-part-8-projections.aspx"&gt;Part 8 – Projections&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/b/vitek/archive/2010/07/15/data-services-expressions-part-9-expansions.aspx"&gt;Part 9 – Expansions&lt;/a&gt;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9969144" width="1" height="1"&gt;</content><author><name>Vitek Karas - MSFT</name><uri>http://blogs.msdn.com/vitkaras/ProfileUrlRedirect.ashx</uri></author><category term="Data Services" scheme="http://blogs.msdn.com/b/vitek/archive/tags/Data+Services/" /><category term="Data Services Expressions" scheme="http://blogs.msdn.com/b/vitek/archive/tags/Data+Services+Expressions/" /><category term="Data Service Provider" scheme="http://blogs.msdn.com/b/vitek/archive/tags/Data+Service+Provider/" /></entry><entry><title>The beginning</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/vitek/archive/2010/02/23/the-beginning.aspx" /><id>http://blogs.msdn.com/b/vitek/archive/2010/02/23/the-beginning.aspx</id><published>2010-02-23T20:51:00Z</published><updated>2010-02-23T20:51:00Z</updated><content type="html">&lt;p&gt;It seems that I’ve finally got to start this blogging thing, exciting times…&lt;/p&gt;  &lt;p&gt;Let me introduce myself - I’m Vitek a developer on the WCF Data Services (aka Astoria) team. In the past I’ve worked on Microsoft’s XML technologies like XmlLite and System.Xml.&lt;/p&gt;  &lt;p&gt;What will you find on my blog? Technical stuff that I find interesting, some samples of things I’m working on and also information that I want to have a permanent link to.&lt;/p&gt;  &lt;p&gt;So, welcome to my blog!&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9968270" width="1" height="1"&gt;</content><author><name>Vitek Karas - MSFT</name><uri>http://blogs.msdn.com/vitkaras/ProfileUrlRedirect.ashx</uri></author></entry></feed>