<?xml version="1.0"?><?xml-stylesheet type="text/xsl" href="/rss.xsl"?><rss version="2.0"><channel><title>ASPNETWebStack Wiki Rss Feed</title><link>http://aspnetwebstack.codeplex.com/</link><description>ASPNETWebStack Wiki Rss Description</description><item><title>Updated Wiki: Web API Request Batching</title><link>https://aspnetwebstack.codeplex.com/wikipage?title=Web API Request Batching&amp;version=6</link><description>&lt;div class="wikidoc"&gt;
&lt;h1&gt;Overview&lt;/h1&gt;
&lt;p&gt;Request batching is a useful way of minimizing the number of messages that are passed between the client and the server. This reduces network traffic and provides a smoother, less chatty user interface. This feature will enable Web API users to batch multiple
 HTTP requests and send them as a single HTTP request.&lt;/p&gt;
&lt;h1&gt;Scenarios&lt;/h1&gt;
&lt;p&gt;To enable batching in general, we’re providing custom message handlers (i.e. DefaultHttpBatchHandler, DefaultODataBatchHandler) which you can register per-route to handle the batch requests.&lt;/p&gt;
&lt;h2&gt;Web API Batching&lt;/h2&gt;
&lt;h3&gt;Registering HTTP batch endpoint&lt;/h3&gt;
&lt;p&gt;You can use &lt;strong&gt;MapHttpBatchRoute&lt;/strong&gt;, which is an HttpRouteCollection extension method, to create a batch endpoint. For example, the following will create a batch endpoint at “api/$batch”.&lt;/p&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Web.Http;
&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Web.Http.Batch;

&lt;span class="kwrd"&gt;namespace&lt;/span&gt; BatchSample
{
    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; WebApiConfig
    {
        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Register(HttpConfiguration config)
        {
            config.Routes.MapHttpBatchRoute(
                routeName: &lt;span class="str"&gt;&amp;quot;WebApiBatch&amp;quot;&lt;/span&gt;, 
                routeTemplate: &lt;span class="str"&gt;&amp;quot;api/$batch&amp;quot;&lt;/span&gt;,
                batchHandler: &lt;span class="kwrd"&gt;new&lt;/span&gt; DefaultHttpBatchHandler(GlobalConfiguration.DefaultServer));

            config.Routes.MapHttpRoute(
                name: &lt;span class="str"&gt;&amp;quot;DefaultApi&amp;quot;&lt;/span&gt;,
                routeTemplate: &lt;span class="str"&gt;&amp;quot;api/{controller}/{id}&amp;quot;&lt;/span&gt;,
                defaults: &lt;span class="kwrd"&gt;new&lt;/span&gt; { id = RouteParameter.Optional }
            );
        }
    }
}&lt;/pre&gt;
&lt;p&gt;That’s all you need to do on the server side. Now, on the client side you can use the existing
&lt;a href="https://nuget.org/packages/Microsoft.AspNet.WebApi.Client/4.1.0-alpha-120809" target="_blank"&gt;
Web API client library&lt;/a&gt; to submit a batch request .&lt;/p&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Net.Http;
&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Net.Http.Formatting;

&lt;span class="kwrd"&gt;namespace&lt;/span&gt; BatchClientSample
{
    &lt;span class="kwrd"&gt;internal&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Program
    {
        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Main(&lt;span class="kwrd"&gt;string&lt;/span&gt;[] args)
        {
            &lt;span class="kwrd"&gt;string&lt;/span&gt; baseAddress = &lt;span class="str"&gt;&amp;quot;http://localhost:8080&amp;quot;&lt;/span&gt;;
            HttpClient client = &lt;span class="kwrd"&gt;new&lt;/span&gt; HttpClient();
            HttpRequestMessage batchRequest = &lt;span class="kwrd"&gt;new&lt;/span&gt; HttpRequestMessage(HttpMethod.Post, baseAddress &amp;#43; &lt;span class="str"&gt;&amp;quot;/api/$batch&amp;quot;&lt;/span&gt;)
            {
                Content = &lt;span class="kwrd"&gt;new&lt;/span&gt; MultipartContent(&lt;span class="str"&gt;&amp;quot;mixed&amp;quot;&lt;/span&gt;)
                {
                    &lt;span class="rem"&gt;// POST http://localhost:8080/api/values&lt;/span&gt;
                    &lt;span class="kwrd"&gt;new&lt;/span&gt; HttpMessageContent(&lt;span class="kwrd"&gt;new&lt;/span&gt; HttpRequestMessage(HttpMethod.Post, baseAddress &amp;#43; &lt;span class="str"&gt;&amp;quot;/api/values&amp;quot;&lt;/span&gt;)
                    {
                        Content = &lt;span class="kwrd"&gt;new&lt;/span&gt; ObjectContent&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt;(&lt;span class="str"&gt;&amp;quot;my value&amp;quot;&lt;/span&gt;, &lt;span class="kwrd"&gt;new&lt;/span&gt; JsonMediaTypeFormatter())
                    }),

                    &lt;span class="rem"&gt;// GET http://localhost:8080/api/values&lt;/span&gt;
                    &lt;span class="kwrd"&gt;new&lt;/span&gt; HttpMessageContent(&lt;span class="kwrd"&gt;new&lt;/span&gt; HttpRequestMessage(HttpMethod.Get, baseAddress &amp;#43; &lt;span class="str"&gt;&amp;quot;/api/values&amp;quot;&lt;/span&gt;))
                }
            };

            HttpResponseMessage batchResponse = client.SendAsync(batchRequest).Result;

            MultipartStreamProvider streamProvider = batchResponse.Content.ReadAsMultipartAsync().Result;
            &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (var content &lt;span class="kwrd"&gt;in&lt;/span&gt; streamProvider.Contents)
            {
                HttpResponseMessage response = content.ReadAsHttpResponseMessageAsync().Result;

                &lt;span class="rem"&gt;// Do something with the response messages&lt;/span&gt;
            }
        }
    }
}&lt;/pre&gt;
&lt;h3&gt;Changing the ExecutionOrder of the DefaultHttpBatchHandler&lt;/h3&gt;
&lt;p&gt;By default each individual batch request is executed sequentially. Meaning the second request in the batch won’t start until the first one is completed. If you have a scenario where the order of execution is not important and you want to execute the requests
 asynchronously, you can set the ExecutionOrder property on the DefaultHttpBatchHandler to NonSequential.&lt;/p&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Web.Http;
&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Web.Http.Batch;

&lt;span class="kwrd"&gt;namespace&lt;/span&gt; BatchSample
{
    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; WebApiConfig
    {
        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Register(HttpConfiguration config)
        {
            HttpBatchHandler batchHandler = &lt;span class="kwrd"&gt;new&lt;/span&gt; DefaultHttpBatchHandler(GlobalConfiguration.DefaultServer)
            {
                ExecutionOrder = BatchExecutionOrder.NonSequential
            };

            config.Routes.MapHttpBatchRoute(
                routeName: &lt;span class="str"&gt;&amp;quot;WebApiBatch&amp;quot;&lt;/span&gt;,
                routeTemplate: &lt;span class="str"&gt;&amp;quot;api/$batch&amp;quot;&lt;/span&gt;,
                batchHandler: batchHandler);

            config.Routes.MapHttpRoute(
                name: &lt;span class="str"&gt;&amp;quot;DefaultApi&amp;quot;&lt;/span&gt;,
                routeTemplate: &lt;span class="str"&gt;&amp;quot;api/{controller}/{id}&amp;quot;&lt;/span&gt;,
                defaults: &lt;span class="kwrd"&gt;new&lt;/span&gt; { id = RouteParameter.Optional }
            );
        }
    }
}&lt;/pre&gt;
&lt;h2&gt;OData Batching&lt;/h2&gt;
&lt;h3&gt;Registering OData batch endpoint&lt;/h3&gt;
&lt;p&gt;You can simply pass an ODataBatchHandler to the MapODataRoute to enable the batching. The batch endpoint will be available at routePrefix/$batch. For instance if you have the following OData route, the batch endpoint will be exposed at “odata/$batch”.&lt;/p&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Web.Http;
&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Web.Http.OData.Batch;
&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Web.Http.OData.Builder;
&lt;span class="kwrd"&gt;using&lt;/span&gt; BatchODataSample.Controllers;
&lt;span class="kwrd"&gt;using&lt;/span&gt; Microsoft.Data.Edm;

&lt;span class="kwrd"&gt;namespace&lt;/span&gt; BatchODataSample
{
    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; WebApiConfig
    {
        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Register(HttpConfiguration config)
        {
            config.Routes.MapODataRoute(
                routeName: &lt;span class="str"&gt;&amp;quot;defaultOdata&amp;quot;&lt;/span&gt;,
                routePrefix: &lt;span class="str"&gt;&amp;quot;odata&amp;quot;&lt;/span&gt;,
                model: GetModel(),
                batchHandler: &lt;span class="kwrd"&gt;new&lt;/span&gt; DefaultODataBatchHandler(GlobalConfiguration.DefaultServer));
        }

        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; IEdmModel GetModel()
        {
            ODataConventionModelBuilder builder = &lt;span class="kwrd"&gt;new&lt;/span&gt; ODataConventionModelBuilder();
            builder.Namespace = &lt;span class="str"&gt;&amp;quot;BatchODataSample.Controllers&amp;quot;&lt;/span&gt;;
            builder.EntitySet&amp;lt;Customer&amp;gt;(&lt;span class="str"&gt;&amp;quot;Customers&amp;quot;&lt;/span&gt;);
            builder.EntitySet&amp;lt;Order&amp;gt;(&lt;span class="str"&gt;&amp;quot;Orders&amp;quot;&lt;/span&gt;);
            &lt;span class="kwrd"&gt;return&lt;/span&gt; builder.GetEdmModel();
        }
    }
}&lt;/pre&gt;
&lt;p&gt;That’s it. Now for the client, you can use &lt;a href="http://msdn.microsoft.com/en-us/library/dd673930.aspx" target="_blank"&gt;
WCF Data Services Client Library&lt;/a&gt;:&lt;/p&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System;
&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Data.Services.Client;
&lt;span class="kwrd"&gt;using&lt;/span&gt; BatchClientSample.ServiceReference1;

&lt;span class="kwrd"&gt;namespace&lt;/span&gt; BatchClientSample
{
    &lt;span class="kwrd"&gt;internal&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Program
    {
        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Main(&lt;span class="kwrd"&gt;string&lt;/span&gt;[] args)
        {
            &lt;span class="kwrd"&gt;string&lt;/span&gt; baseAddress = &lt;span class="str"&gt;&amp;quot;http://localhost:8080/odata&amp;quot;&lt;/span&gt;;
            Container container = &lt;span class="kwrd"&gt;new&lt;/span&gt; Container(&lt;span class="kwrd"&gt;new&lt;/span&gt; Uri(baseAddress));

            &lt;span class="kwrd"&gt;int&lt;/span&gt; id = &lt;span class="kwrd"&gt;new&lt;/span&gt; Random().Next();
            var customer = &lt;span class="kwrd"&gt;new&lt;/span&gt; Customer { ID = id, Name = &lt;span class="str"&gt;&amp;quot;User&amp;quot;&lt;/span&gt; &amp;#43; id };
            var order = &lt;span class="kwrd"&gt;new&lt;/span&gt; Order { ID = id, Amount = id &amp;#43; 10 };

            &lt;span class="rem"&gt;// Batch operation.&lt;/span&gt;
            container.AddToCustomers(customer);
            container.AddToOrders(order);
            container.AddLink(customer, &lt;span class="str"&gt;&amp;quot;Orders&amp;quot;&lt;/span&gt;, order);

            var batchResponse = container.SaveChanges(SaveChangesOptions.Batch);

            &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (var response &lt;span class="kwrd"&gt;in&lt;/span&gt; batchResponse)
            {
                Console.WriteLine(response.StatusCode);
                Console.WriteLine(response.Headers);
            }
        }
    }
}&lt;/pre&gt;
&lt;p&gt;Or &lt;a href="http://datajs.codeplex.com/" target="_blank"&gt;datajs&lt;/a&gt; (or any JavaScript library that supports sending OData batch requests):&lt;/p&gt;
&lt;pre class="csharpcode"&gt;OData.request({
    requestUri: &lt;span class="str"&gt;&amp;quot;/odata/$batch&amp;quot;&lt;/span&gt;,
    method: &lt;span class="str"&gt;&amp;quot;POST&amp;quot;&lt;/span&gt;,
    data: {
        __batchRequests: [
            { __changeRequests: [
                { requestUri: &lt;span class="str"&gt;&amp;quot;Customers&amp;quot;&lt;/span&gt;, method: &lt;span class="str"&gt;&amp;quot;POST&amp;quot;&lt;/span&gt;, data: customer }
            ] },
            { requestUri: &lt;span class="str"&gt;&amp;quot;Customers&amp;quot;&lt;/span&gt;, method: &lt;span class="str"&gt;&amp;quot;GET&amp;quot;&lt;/span&gt; }
        ]
    }
}, &lt;span class="kwrd"&gt;function&lt;/span&gt; (data, response) {
    &lt;span class="rem"&gt;//success handler&lt;/span&gt;
}, &lt;span class="kwrd"&gt;function&lt;/span&gt; () {
    alert(&lt;span class="str"&gt;&amp;quot;request failed&amp;quot;&lt;/span&gt;);
}, OData.batchHandler);&lt;/pre&gt;
&lt;h3&gt;Setting up multiple OData routes and the batch endpoints&lt;/h3&gt;
&lt;p&gt;You can have multiple OData routes with their own batch endpoints. For example, the following will setup the batch endpoints at “catalog/$batch” and “commerce/$batch”.&lt;/p&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Register(HttpConfiguration config)
{
    config.Routes.MapODataRoute(
        routeName: &lt;span class="str"&gt;&amp;quot;odata1&amp;quot;&lt;/span&gt;,
        routePrefix: &lt;span class="str"&gt;&amp;quot;catalog&amp;quot;&lt;/span&gt;,
        model: GetModel(),
        batchHandler: &lt;span class="kwrd"&gt;new&lt;/span&gt; DefaultODataBatchHandler(GlobalConfiguration.DefaultServer));

    config.Routes.MapODataRoute(
        routeName: &lt;span class="str"&gt;&amp;quot;odata2&amp;quot;&lt;/span&gt;,
        routePrefix: &lt;span class="str"&gt;&amp;quot;commerce&amp;quot;&lt;/span&gt;,
        model: GetModel2(),
        batchHandler: &lt;span class="kwrd"&gt;new&lt;/span&gt; DefaultODataBatchHandler(GlobalConfiguration.DefaultServer));
}&lt;/pre&gt;
&lt;p&gt;Note that the ODataBatchHandler instance cannot be shared across routes if you want to support relative URI in the OData batch requests. For example, the following request constructed using datajs will submit a batch request to “/commerce/$batch” but the
 requestUri for the sub-requests are simply “Customers”. In this case the ODataBatchHandler need to be aware of the OData route where it’s registered to figure out the right route prefix (in this case “commerce”) for the requestUri.&lt;/p&gt;
&lt;pre class="csharpcode"&gt;OData.request({
    requestUri: &lt;span class="str"&gt;&amp;quot;/commerce/$batch&amp;quot;&lt;/span&gt;,
    method: &lt;span class="str"&gt;&amp;quot;POST&amp;quot;&lt;/span&gt;,
    data: {
        __batchRequests: [
            { __changeRequests: [
                { requestUri: &lt;span class="str"&gt;&amp;quot;Customers&amp;quot;&lt;/span&gt;, method: &lt;span class="str"&gt;&amp;quot;POST&amp;quot;&lt;/span&gt;, data: customer }
            ] },
            { requestUri: &lt;span class="str"&gt;&amp;quot;Customers&amp;quot;&lt;/span&gt;, method: &lt;span class="str"&gt;&amp;quot;GET&amp;quot;&lt;/span&gt; }
        ]
    }
}, &lt;span class="kwrd"&gt;function&lt;/span&gt; (data, response) {
    &lt;span class="rem"&gt;//success handler&lt;/span&gt;
}, &lt;span class="kwrd"&gt;function&lt;/span&gt; () {
    alert(&lt;span class="str"&gt;&amp;quot;request failed&amp;quot;&lt;/span&gt;);
}, OData.batchHandler);&lt;/pre&gt;
&lt;h3&gt;Setting Batch Quotas&lt;/h3&gt;
&lt;p&gt;You can set the throttle on the Batch by setting the MessageQuotas on the ODataBatchHandler. For instance, the following setting will only allow a maximum of 10 requests per batch and 10 operations per ChangeSet.&lt;/p&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Web.Http;
&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Web.Http.OData.Batch;
&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Web.Http.OData.Builder;
&lt;span class="kwrd"&gt;using&lt;/span&gt; BatchODataSample.Controllers;
&lt;span class="kwrd"&gt;using&lt;/span&gt; Microsoft.Data.Edm;

&lt;span class="kwrd"&gt;namespace&lt;/span&gt; BatchODataSample
{
    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; WebApiConfig
    {
        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Register(HttpConfiguration config)
        {
            ODataBatchHandler odataBatchHandler = &lt;span class="kwrd"&gt;new&lt;/span&gt; DefaultODataBatchHandler(GlobalConfiguration.DefaultServer);
            odataBatchHandler.MessageQuotas.MaxOperationsPerChangeset = 10;
            odataBatchHandler.MessageQuotas.MaxPartsPerBatch = 10;

            config.Routes.MapODataRoute(
                routeName: &lt;span class="str"&gt;&amp;quot;defaultOdata&amp;quot;&lt;/span&gt;,
                routePrefix: &lt;span class="str"&gt;&amp;quot;odata&amp;quot;&lt;/span&gt;,
                model: GetModel(),
                batchHandler: odataBatchHandler);
        }

        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; IEdmModel GetModel()
        {
            ODataConventionModelBuilder builder = &lt;span class="kwrd"&gt;new&lt;/span&gt; ODataConventionModelBuilder();
            builder.Namespace = &lt;span class="str"&gt;&amp;quot;BatchODataSample.Controllers&amp;quot;&lt;/span&gt;;
            builder.EntitySet&amp;lt;Customer&amp;gt;(&lt;span class="str"&gt;&amp;quot;Customers&amp;quot;&lt;/span&gt;);
            builder.EntitySet&amp;lt;Order&amp;gt;(&lt;span class="str"&gt;&amp;quot;Orders&amp;quot;&lt;/span&gt;);
            &lt;span class="kwrd"&gt;return&lt;/span&gt; builder.GetEdmModel();
        }
    }
}&lt;/pre&gt;
&lt;h3&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h2&gt;Custom Batching&lt;/h2&gt;
&lt;p&gt;You can derive from either HttpBatchHandler or DefaultHttpBatchHandler to support custom batch formats. For instance, instead of using MIME multipart, you can use JSON as the format for the batch requests just like
&lt;a href="https://developers.facebook.com/docs/reference/api/batch/" target="_blank"&gt;
Facebook batch requests&lt;/a&gt;. &lt;/p&gt;
&lt;p&gt;Here is a naïve implementation of HttpBatchHandler that encodes the batch requests/responses as JSON. It simply derives from DefaultHttpBatchHandler, overrides the ParseBatchRequestsAsync/CreateResponseMessageAsync methods and let the base class handle the
 rest.&lt;/p&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System;
&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Collections.Generic;
&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Linq;
&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Net;
&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Net.Http;
&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Threading.Tasks;
&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Web.Http;
&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Web.Http.Batch;

&lt;span class="kwrd"&gt;namespace&lt;/span&gt; BatchSample
{
    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; JsonBatchHandler : DefaultHttpBatchHandler
    {
        &lt;span class="kwrd"&gt;public&lt;/span&gt; JsonBatchHandler(HttpServer server)
            : &lt;span class="kwrd"&gt;base&lt;/span&gt;(server)
        {
            SupportedContentTypes.Add(&lt;span class="str"&gt;&amp;quot;text/json&amp;quot;&lt;/span&gt;);
            SupportedContentTypes.Add(&lt;span class="str"&gt;&amp;quot;application/json&amp;quot;&lt;/span&gt;);
        }

        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; async Task&amp;lt;IList&amp;lt;HttpRequestMessage&amp;gt;&amp;gt; ParseBatchRequestsAsync(HttpRequestMessage request)
        {
            var jsonSubRequests = await request.Content.ReadAsAsync&amp;lt;JsonRequestMessage[]&amp;gt;();

            &lt;span class="rem"&gt;// Creating simple requests, no headers nor bodies&lt;/span&gt;
            var subRequests = jsonSubRequests.Select(r =&amp;gt;
            {
                Uri subRequestUri = &lt;span class="kwrd"&gt;new&lt;/span&gt; Uri(request.RequestUri, &lt;span class="str"&gt;&amp;quot;/&amp;quot;&lt;/span&gt; &amp;#43; r.relative_url);
                &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; HttpRequestMessage(&lt;span class="kwrd"&gt;new&lt;/span&gt; HttpMethod(r.method), subRequestUri);
            });
            &lt;span class="kwrd"&gt;return&lt;/span&gt; subRequests.ToList();
        }

        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; async Task&amp;lt;HttpResponseMessage&amp;gt; CreateResponseMessageAsync(IList&amp;lt;HttpResponseMessage&amp;gt; responses,
                                                                                   HttpRequestMessage request)
        {
            List&amp;lt;JsonResponseMessage&amp;gt; jsonResponses = &lt;span class="kwrd"&gt;new&lt;/span&gt; List&amp;lt;JsonResponseMessage&amp;gt;();
            &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (var subResponse &lt;span class="kwrd"&gt;in&lt;/span&gt; responses)
            {
                var jsonResponse = &lt;span class="kwrd"&gt;new&lt;/span&gt; JsonResponseMessage
                {
                    code = (&lt;span class="kwrd"&gt;int&lt;/span&gt;)subResponse.StatusCode
                };
                &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (var header &lt;span class="kwrd"&gt;in&lt;/span&gt; subResponse.Headers)
                {
                    jsonResponse.headers.Add(header.Key, String.Join(&lt;span class="str"&gt;&amp;quot;,&amp;quot;&lt;/span&gt;, header.Value));
                }
                &lt;span class="kwrd"&gt;if&lt;/span&gt; (subResponse.Content != &lt;span class="kwrd"&gt;null&lt;/span&gt;)
                {
                    jsonResponse.body = await subResponse.Content.ReadAsStringAsync();
                    &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (var header &lt;span class="kwrd"&gt;in&lt;/span&gt; subResponse.Content.Headers)
                    {
                        jsonResponse.headers.Add(header.Key, String.Join(&lt;span class="str"&gt;&amp;quot;,&amp;quot;&lt;/span&gt;, header.Value));
                    }
                }
                jsonResponses.Add(jsonResponse);
            }

            &lt;span class="kwrd"&gt;return&lt;/span&gt; request.CreateResponse&amp;lt;List&amp;lt;JsonResponseMessage&amp;gt;&amp;gt;(HttpStatusCode.OK, jsonResponses);
        }
    }

    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; JsonResponseMessage
    {
        &lt;span class="kwrd"&gt;public&lt;/span&gt; JsonResponseMessage()
        {
            headers = &lt;span class="kwrd"&gt;new&lt;/span&gt; Dictionary&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;, &lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt;();
        }

        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; code { get; set; }

        &lt;span class="kwrd"&gt;public&lt;/span&gt; Dictionary&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;, &lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt; headers { get; set; }

        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; body { get; set; }
    }

    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; JsonRequestMessage
    {
        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; method { get; set; }

        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; relative_url { get; set; }
    }
}&lt;/pre&gt;
&lt;p&gt;Just like with any other HttpBatchHandler, you can register the batch endpoint using MapHttpBatchRoute.&lt;/p&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Web.Http;
&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Web.Http.Batch;
&lt;span class="kwrd"&gt;using&lt;/span&gt; BatchSample;

&lt;span class="kwrd"&gt;namespace&lt;/span&gt; BatchRequestSample
{
    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; WebApiConfig
    {
        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Register(HttpConfiguration config)
        {
            config.Routes.MapHttpBatchRoute(
                routeName: &lt;span class="str"&gt;&amp;quot;WebApiBatch&amp;quot;&lt;/span&gt;,
                routeTemplate: &lt;span class="str"&gt;&amp;quot;api/$batch&amp;quot;&lt;/span&gt;,
                batchHandler: &lt;span class="kwrd"&gt;new&lt;/span&gt; DefaultHttpBatchHandler(GlobalConfiguration.DefaultServer));

            config.Routes.MapHttpBatchRoute(
                routeName: &lt;span class="str"&gt;&amp;quot;WebApiBatchJson&amp;quot;&lt;/span&gt;,
                routeTemplate: &lt;span class="str"&gt;&amp;quot;api/$batchJson&amp;quot;&lt;/span&gt;,
                batchHandler: &lt;span class="kwrd"&gt;new&lt;/span&gt; JsonBatchHandler(GlobalConfiguration.DefaultServer));

            config.Routes.MapHttpRoute(
                name: &lt;span class="str"&gt;&amp;quot;DefaultApi&amp;quot;&lt;/span&gt;,
                routeTemplate: &lt;span class="str"&gt;&amp;quot;api/{controller}/{id}&amp;quot;&lt;/span&gt;,
                defaults: &lt;span class="kwrd"&gt;new&lt;/span&gt; { id = RouteParameter.Optional }
            );
        }
    }
}&lt;/pre&gt;
&lt;h1&gt;Design&lt;/h1&gt;
&lt;h2&gt;HttpBatchHandler&lt;/h2&gt;
&lt;p&gt;This is a custom HttpMessageHandler that is used to handle the batch requests. The HttpBatchHandler takes an HttpServer in the constructor and use it to dispatch the sub-requests.&lt;/p&gt;
&lt;p&gt;HttpBatchHandler is an abstract class and an implementation of HttpBatchHandler will typically do the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Parse the incoming request into sub-requests &lt;/li&gt;&lt;li&gt;Execute the batch requests &lt;/li&gt;&lt;li&gt;Build the batch response &lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;Here is a high level overview of how HttpBatchHandler interacts with other handlers/dispatchers in the Web API pipeline. Note that the HttpBatchHandler is registered as a per-route handler as you’ve seen in the sample code above.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://download-codeplex.sec.s-msft.com/Download?ProjectName=aspnetwebstack&amp;DownloadId=665012"&gt;&lt;img title="image" border="0" alt="image" src="http://download-codeplex.sec.s-msft.com/Download?ProjectName=aspnetwebstack&amp;DownloadId=665013" width="750" height="509" style="border-left-width:0px; border-right-width:0px; border-bottom-width:0px; padding-top:0px; padding-left:0px; display:inline; padding-right:0px; border-top-width:0px"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;HttpBatchHandler Implementations&lt;/h2&gt;
&lt;p&gt;Out of the box, we provide different HttpBatchHandler implementations to support simple Web API batching as well as OData batching. Here is an overview of the HttpBatchHandler hierarchy.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://download-codeplex.sec.s-msft.com/Download?ProjectName=aspnetwebstack&amp;DownloadId=665014"&gt;&lt;img title="ClassDiagram2" border="0" alt="ClassDiagram2" src="http://download-codeplex.sec.s-msft.com/Download?ProjectName=aspnetwebstack&amp;DownloadId=665015" width="550" height="606" style="border-left-width:0px; border-right-width:0px; border-bottom-width:0px; padding-top:0px; padding-left:0px; display:inline; padding-right:0px; border-top-width:0px"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;DefaultHttpBatchHandler&lt;/h3&gt;
&lt;p&gt;This is a simple batch handler that encodes the HTTP request/response messages as MIME multipart. By default, it buffers the HTTP request messages in-memory during parsing. The DefaultHttpBatchHandler has several virtual methods which you can use to extend
 and customize.&lt;/p&gt;
&lt;h3&gt;ODataHttpBatchHandler&lt;/h3&gt;
&lt;p&gt;For OData batching we provide two implementations:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;DefaultODataBatchHandler&lt;/strong&gt; – Supports OData batch formats, sub-requests are sent once all the sub-requests are read, it buffers the content stream of the sub-requests.
&lt;/li&gt;&lt;li&gt;&lt;strong&gt;UnbufferedODataBatchHandler&lt;/strong&gt; – Supports OData batch formats, individual sub-request is sent as soon as it is read, it doesn’t buffer the content stream of the sub-requests.&lt;/li&gt;&lt;/ul&gt;
&lt;h4&gt;Why can’t I set ExecutionOrder in ODataHttpBatchHandler like in DefaultHttpBatchHandler?&lt;/h4&gt;
&lt;p&gt;The OData spec has the execution order defined and it could be problematic if changed because the client can make certain assumptions based on the spec. By definition, the operation/ChangeSet within a batch request is executed in ordered manner. Although
 the operations within the ChangeSet can be executed regardless of the order but our implementation will execute them sequentially for simplicity (easier to deal with Content-ID references).&lt;/p&gt;
&lt;h4&gt;Content-ID references&lt;/h4&gt;
&lt;p&gt;We do support Content-ID header which is a mechanism used for referencing requests in a ChangeSet. Here is the description from the
&lt;a href="http://www.odata.org/documentation/odata-v3-documentation/batch-processing/#221_Referencing_Requests_in_a_Change_Set" target="_blank"&gt;
OData spec&lt;/a&gt;: “If a MIME part representing an Insert request within a ChangeSet includes a Content-ID header, then the new entity may be referenced by subsequent requests within the same ChangeSet by referring to the Content-ID value prefixed with a &amp;quot;$&amp;quot; character.
 When used in this way, $&amp;lt;contentIdValue&amp;gt; acts as an alias for the Resource Path that identifies the new entity.”&lt;/p&gt;
&lt;p&gt;The way how we implement this is by building a Content-ID to Location header dictionary when processing the ChangeSet. After sending each request in the ChangeSet, we build the dictionary using the Content-ID header from the request and the Location header
 from the response.&amp;nbsp; And before sending each request in the ChangeSet, we use the dictionary to replace the $&amp;lt;contentIdValue&amp;gt;&amp;nbsp; in the request URI with the Location.&lt;/p&gt;
&lt;h1&gt;Raw Batch Formats&lt;/h1&gt;
&lt;h2&gt;DefaultHttpBatchHandler &lt;/h2&gt;
&lt;h3&gt;Sample Request&lt;/h3&gt;
&lt;pre class="csharpcode"&gt;POST http://localhost:8080/api/$batch HTTP/1.1
Content-Type: multipart/mixed; boundary=&amp;quot;91731eeb-d443-4aa6-9816-560a8aca66b1&amp;quot;
Host: localhost:8080
Content-Length: 390
Expect: 100-continue
Connection: Keep-Alive

--91731eeb-d443-4aa6-9816-560a8aca66b1
Content-Type: application/http; msgtype=request

POST /api/values HTTP/1.1
Host: localhost:8080
Content-Type: application/json; charset=utf-8

&amp;quot;my value&amp;quot;
--91731eeb-d443-4aa6-9816-560a8aca66b1
Content-Type: application/http; msgtype=request

GET /api/values HTTP/1.1
Host: localhost:8080


--91731eeb-d443-4aa6-9816-560a8aca66b1--&lt;/pre&gt;
&lt;h3&gt;Sample Response&lt;/h3&gt;
&lt;pre class="csharpcode"&gt;HTTP/1.1 200 OK
Content-Length: 333
Content-Type: multipart/mixed; boundary=&amp;quot;5b2a806d-4040-43f0-8f04-7d4c86793fa7&amp;quot;
Server: Microsoft-HTTPAPI/2.0
Date: Mon, 08 Apr 2013 19:00:26 GMT

--5b2a806d-4040-43f0-8f04-7d4c86793fa7
Content-Type: application/http; msgtype=response

HTTP/1.1 202 Accepted


--5b2a806d-4040-43f0-8f04-7d4c86793fa7
Content-Type: application/http; msgtype=response

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

[&amp;quot;my value&amp;quot;]
--5b2a806d-4040-43f0-8f04-7d4c86793fa7--&lt;/pre&gt;
&lt;h2&gt;DefaultODataBatchHandler/UnbufferedODataBatchHandler&lt;/h2&gt;
&lt;h3&gt;Sample Request&lt;/h3&gt;
&lt;pre class="csharpcode"&gt;POST /service/$batch HTTP/1.1 
Host: host 
Content-Type: multipart/mixed; boundary=batch_36522ad7-fc75-4b56-8c71-56071383e77b 

--batch_36522ad7-fc75-4b56-8c71-56071383e77b 
Content-Type: multipart/mixed; boundary=changeset_77162fcd-b8da-41ac-a9f8-9357efbbd621 
Content-Length: ###       

--changeset(77162fcd-b8da-41ac-a9f8-9357efbbd621) 
Content-Type: application/http 
Content-Transfer-Encoding: binary 
Content-ID: 1 

POST /service/Customers HTTP/1.1 
Host: host  
Content-Type: application/atom&amp;#43;xml;type=entry 
Content-Length: ### 

&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;AtomPub&lt;/span&gt; &lt;span class="attr"&gt;representation&lt;/span&gt; &lt;span class="attr"&gt;of&lt;/span&gt; &lt;span class="attr"&gt;a&lt;/span&gt; &lt;span class="attr"&gt;new&lt;/span&gt; &lt;span class="attr"&gt;Customer&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt; 

--changeset(77162fcd-b8da-41ac-a9f8-9357efbbd621) 
Content-Type: application/http 
Content-Transfer-Encoding: binary 

POST $1/Orders HTTP/1.1 
Host: host 
Content-Type: application/atom&amp;#43;xml;type=entry 
Content-Length: ### 

&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;AtomPub&lt;/span&gt; &lt;span class="attr"&gt;representation&lt;/span&gt; &lt;span class="attr"&gt;of&lt;/span&gt; &lt;span class="attr"&gt;a&lt;/span&gt; &lt;span class="attr"&gt;new&lt;/span&gt; &lt;span class="attr"&gt;Order&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt; 

--changeset(77162fcd-b8da-41ac-a9f8-9357efbbd621)-- 
--batch(36522ad7-fc75-4b56-8c71-56071383e77b)--&lt;/pre&gt;
&lt;h3&gt;Sample Response&lt;/h3&gt;
&lt;pre class="csharpcode"&gt;HTTP/1.1 202 Accepted
DataServiceVersion: 1.0
Content-Length: ####
Content-Type: multipart/mixed; boundary=batch(36522ad7-fc75-4b56-8c71-56071383e77b)

--batch(36522ad7-fc75-4b56-8c71-56071383e77b)
Content-Type: application/http
Content-Transfer-Encoding: binary

HTTP/1.1 200 Ok
Content-Type: application/atom&amp;#43;xml;type=entry
Content-Length: ###

&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;AtomPub&lt;/span&gt; &lt;span class="attr"&gt;representation&lt;/span&gt; &lt;span class="attr"&gt;of&lt;/span&gt; &lt;span class="attr"&gt;the&lt;/span&gt; &lt;span class="attr"&gt;Customer&lt;/span&gt; &lt;span class="attr"&gt;entity&lt;/span&gt; &lt;span class="attr"&gt;with&lt;/span&gt; &lt;span class="attr"&gt;EntityKey&lt;/span&gt; &lt;span class="attr"&gt;ALFKI&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;

--batch(36522ad7-fc75-4b56-8c71-56071383e77b)
Content-Type: multipart/mixed; boundary=changeset(77162fcd-b8da-41ac-a9f8-9357efbbd621)
Content-Length: ###      

--changeset(77162fcd-b8da-41ac-a9f8-9357efbbd621)
Content-Type: application/http
Content-Transfer-Encoding: binary

HTTP/1.1 201 Created
Content-Type: application/atom&amp;#43;xml;type=entry
Location: http://host/service.svc/Customer('POIUY')
Content-Length: ###

&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;AtomPub&lt;/span&gt; &lt;span class="attr"&gt;representation&lt;/span&gt; &lt;span class="attr"&gt;of&lt;/span&gt; &lt;span class="attr"&gt;a&lt;/span&gt; &lt;span class="attr"&gt;new&lt;/span&gt; &lt;span class="attr"&gt;Customer&lt;/span&gt; &lt;span class="attr"&gt;entity&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;

--changeset(77162fcd-b8da-41ac-a9f8-9357efbbd621)
Content-Type: application/http
Content-Transfer-Encoding: binary

HTTP/1.1 204 No Content
Host: host

--changeset(77162fcd-b8da-41ac-a9f8-9357efbbd621)--

--batch(36522ad7-fc75-4b56-8c71-56071383e77b)
Content-Type: application/http
Content-Transfer-Encoding: binary

HTTP/1.1 404 Not Found
Content-Type: application/xml
Content-Length: ###

&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Error&lt;/span&gt; &lt;span class="attr"&gt;message&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
--batch(36522ad7-fc75-4b56-8c71-56071383e77b)--&lt;/pre&gt;
&lt;/div&gt;&lt;div class="ClearBoth"&gt;&lt;/div&gt;</description><author>yaohuang</author><pubDate>Mon, 13 May 2013 17:28:58 GMT</pubDate><guid isPermaLink="false">Updated Wiki: Web API Request Batching 20130513052858P</guid></item><item><title>New Comment on "$select and $expand support"</title><link>https://aspnetwebstack.codeplex.com/wikipage?title=$select and $expand support&amp;ANCHOR#C27459</link><description>Expand doesn&amp;#39;t work if I try to get entity by key&amp;#63;&amp;#10;http&amp;#58;&amp;#47;&amp;#47;server&amp;#47;Customers&amp;#40;1&amp;#41;&amp;#63;&amp;#36;expand&amp;#61;Orders</description><author>RomanBats</author><pubDate>Sun, 12 May 2013 09:50:08 GMT</pubDate><guid isPermaLink="false">New Comment on "$select and $expand support" 20130512095008A</guid></item><item><title>New Comment on "CORS support for ASP.NET Web API"</title><link>https://aspnetwebstack.codeplex.com/wikipage?title=CORS support for ASP.NET Web API&amp;ANCHOR#C27451</link><description>I have got the answer for this ....check Yao&amp;#39;s blog for the answer&amp;#58;&amp;#10;&amp;#10;http&amp;#58;&amp;#47;&amp;#47;blogs.msdn.com&amp;#47;b&amp;#47;yaohuang1&amp;#47;archive&amp;#47;2013&amp;#47;04&amp;#47;05&amp;#47;try-out-asp.net-web-api-cors-support-using-the-nightly-builds.aspx&amp;#10;&amp;#10;thanks a lot&amp;#33;</description><author>amarta78</author><pubDate>Sat, 11 May 2013 00:35:53 GMT</pubDate><guid isPermaLink="false">New Comment on "CORS support for ASP.NET Web API" 20130511123553A</guid></item><item><title>New Comment on "CORS support for ASP.NET Web API"</title><link>https://aspnetwebstack.codeplex.com/wikipage?title=CORS support for ASP.NET Web API&amp;ANCHOR#C27438</link><description>I get a compiler error saying that EnableCorsAttribute does not contain a constructor that takes 0 arguments. Can you please let us know why we get this&amp;#63;</description><author>amarta78</author><pubDate>Fri, 10 May 2013 01:04:14 GMT</pubDate><guid isPermaLink="false">New Comment on "CORS support for ASP.NET Web API" 20130510010414A</guid></item><item><title>Updated Wiki: $select and $expand support</title><link>https://aspnetwebstack.codeplex.com/wikipage?title=$select and $expand support&amp;version=27</link><description>&lt;div class="wikidoc"&gt;&lt;h1&gt;$select and $expand support&lt;/h1&gt;&lt;hr /&gt;
The $select system query option allows clients to requests a limited set of information for each entity or complex type identified by the ResourcePath and other System Query Options like $filter, $top, $skip etc. The $select query option is often used in conjunction with the $expand query option, to first increase the scope of the resource graph returned ($expand) and then selectively prune that resource graph ($select).&lt;br /&gt;&lt;br /&gt;The $expand system query option allows clients to request related resources when a resource that satisfies a particular request is retrieved.&lt;br /&gt;&lt;br /&gt;The following model would be used for the rest of the scenarios,&lt;br /&gt;&lt;br /&gt;&lt;div style="color:Black;background-color:White;"&gt;&lt;pre&gt;
&lt;span style="color:Blue;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;"&gt;class&lt;/span&gt; Customer
{
    &lt;span style="color:Blue;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;"&gt;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&lt;/span&gt; &lt;span style="color:Blue;"&gt;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:Blue;"&gt;virtual&lt;/span&gt; ICollection&amp;lt;Order&amp;gt; Orders { &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:Blue;"&gt;class&lt;/span&gt; SpecialCustomer : Customer
{
    &lt;span style="color:Blue;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;"&gt;int&lt;/span&gt; SpecialCustomerProperty { &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:Blue;"&gt;virtual&lt;/span&gt; ICollection&amp;lt;SpecialOrder&amp;gt; SpecialOrders { &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:Blue;"&gt;class&lt;/span&gt; Order
{
    &lt;span style="color:Blue;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;"&gt;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&lt;/span&gt; &lt;span style="color:Blue;"&gt;int&lt;/span&gt; Amount { &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; Customer Customer { &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:Blue;"&gt;class&lt;/span&gt; SpecialOrder : Order
{
    &lt;span style="color:Blue;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;"&gt;int&lt;/span&gt; SpecialOrderProperty { &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:Blue;"&gt;virtual&lt;/span&gt; SpecialCustomer SpecialCustomer { &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;private&lt;/span&gt; &lt;span style="color:Blue;"&gt;static&lt;/span&gt; IEdmModel GetModel()
{
    ODataConventionModelBuilder builder = &lt;span style="color:Blue;"&gt;new&lt;/span&gt; ODataConventionModelBuilder();
    builder.EntitySet&amp;lt;Customer&amp;gt;(&lt;span style="color:#A31515;"&gt;&amp;quot;Customers&amp;quot;&lt;/span&gt;);
    builder.EntitySet&amp;lt;Order&amp;gt;(&lt;span style="color:#A31515;"&gt;&amp;quot;Orders&amp;quot;&lt;/span&gt;);
    &lt;span style="color:Blue;"&gt;return&lt;/span&gt; builder.GetEdmModel();
}
&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;For example, assuming that a service exposes two entity sets ‘Customers’ and ‘Orders’ and a customer has 1..* (one-to-many) relationship with order, the following URL’s are valid,&lt;br /&gt;
&lt;h3&gt;Supported scenarios&lt;/h3&gt;&lt;a href="http://server/Customers?$select=Id,Name"&gt;http://server/Customers?$select=Id,Name&lt;/a&gt; &lt;br /&gt;Response should contain only the properties Id and Name for each customer. Navigation link for the property Orders must not be present in the response.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://server/Customers?$expand=Orders"&gt;http://server/Customers?$expand=Orders&lt;/a&gt; &lt;br /&gt;Response should contain all the properties of Customer for each customer. It should also contain the expanded Orders for each customer along with the navigation link (depending on the metadata level though). The expanded Orders should contain all structural properties of Orders and navigation link for each navigation property on Order.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://server/Customers?$select=Id,Name,Orders&amp;amp;$expand=Orders"&gt;http://server/Customers?$select=Id,Name,Orders&amp;amp;$expand=Orders&lt;/a&gt; &lt;br /&gt;Response should contain properties Id and Name for each customer and expanded Orders. Each expanded Order should contain all the structural properties of order and a navigation link for each navigation property of order.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://server/Customers?$select=Orders/Id&amp;amp;$expand=Orders"&gt;http://server/Customers?$select=Orders/Id&amp;amp;$expand=Orders&lt;/a&gt; &lt;br /&gt;Selection on an expanded property.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://server/Customers?$select=Id,NS.SpecialCustomer/SpecialId"&gt;http://server/Customers?$select=Id,NS.SpecialCustomer/SpecialId&lt;/a&gt; &lt;br /&gt;Response should contain Id property for each customer and also includes the SpecialId property for each special customer. ODataLib uri parser doesn’t support this yet.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://server/Customers?$expand=NS.SpecialCustomer/SpecialOrder"&gt;http://server/Customers?$expand=NS.SpecialCustomer/SpecialOrder&lt;/a&gt; &lt;br /&gt;Response should contain all structural properties and expand the SpecialOrder property for each special customer. A normal customer would have his navigation links as deferred content in the response. ODataLib uri parser doesn’t support this yet.&lt;br /&gt;&lt;br /&gt;
&lt;h3&gt;Not supported scenarios&lt;/h3&gt;&lt;a href="http://server/Customers(42)/Address?$select=City"&gt;http://server/Customers(42)/Address?$select=City&lt;/a&gt;&lt;br /&gt;Selections of complex types is not supported. (OData V4 might have support for it though)&lt;br /&gt;
&lt;h3&gt;Samples&lt;/h3&gt;
&lt;h4&gt;1) Supporting $select and $expand on collections through QueryableAttribute.&lt;/h4&gt;&lt;div style="color:Black;background-color:White;"&gt;&lt;pre&gt;
[Queryable]
&lt;span style="color:Blue;"&gt;public&lt;/span&gt; IQueryable&amp;lt;Customer&amp;gt; GetCustomers()
{
    &lt;span style="color:Blue;"&gt;return&lt;/span&gt; _dbContext.Customers;
}
&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;2) Supporting $select and $expand on single entities through QueryableAttribute.&lt;/h4&gt;&lt;div style="color:Black;background-color:White;"&gt;&lt;pre&gt;
[Queryable]
&lt;span style="color:Blue;"&gt;public&lt;/span&gt; SingleResult&amp;lt;Customer&amp;gt; GetCustomer(&lt;span style="color:Blue;"&gt;int&lt;/span&gt; id)
{
    &lt;span style="color:Blue;"&gt;return&lt;/span&gt; SingleResult.Create(_dbContext.Customers.Where(c =&amp;gt; c.ID == id);
}
&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;3) Supporting $select and $expand on single entities when you don&amp;#39;t have a db context (Linq2Objects).&lt;/h4&gt;&lt;div style="color:Black;background-color:White;"&gt;&lt;pre&gt;
[Queryable]
&lt;span style="color:Blue;"&gt;public&lt;/span&gt; Customer GetCustomer(&lt;span style="color:Blue;"&gt;int&lt;/span&gt; id)
{
    &lt;span style="color:Blue;"&gt;return&lt;/span&gt; _repository.Find(id);
}
&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;4) Supporting $select and $expand with ODataQueryOptions&amp;lt;T&amp;gt;&lt;/h4&gt;This is more complex than usual as Request.CreateResponse doesn&amp;#39;t have a non generic implementation. There is only Request.CreateResponse&amp;lt;T&amp;gt;. This is beign tracked with this &lt;a href="https://aspnetwebstack.codeplex.com/workitem/883"&gt;bug&lt;/a&gt; &lt;br /&gt;&lt;div style="color:Black;background-color:White;"&gt;&lt;pre&gt;
&lt;span style="color:Blue;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;"&gt;class&lt;/span&gt; CustomersController : ODataController
{
    &lt;span style="color:Blue;"&gt;private&lt;/span&gt; CustomersContext _db = &lt;span style="color:Blue;"&gt;new&lt;/span&gt; CustomersContext();

    &lt;span style="color:Blue;"&gt;public&lt;/span&gt; HttpResponseMessage GetCustomers(ODataQueryOptions&amp;lt;Customer&amp;gt; query)
    {
        &lt;span style="color:Blue;"&gt;return&lt;/span&gt; CreateQueryableResponse(Request, query.ApplyTo(_db.Customers));
    }

    &lt;span style="color:Blue;"&gt;private&lt;/span&gt; &lt;span style="color:Blue;"&gt;static&lt;/span&gt; HttpResponseMessage CreateQueryableResponse(HttpRequestMessage request, IQueryable queryable)
    {
        MethodInfo mi = &lt;span style="color:Blue;"&gt;typeof&lt;/span&gt;(CustomersController).GetMethod(&lt;span style="color:#A31515;"&gt;&amp;quot;CreateQueryableResponseImpl&amp;quot;&lt;/span&gt;, BindingFlags.Static | BindingFlags.NonPublic);
        mi = mi.MakeGenericMethod(queryable.ElementType);
        &lt;span style="color:Blue;"&gt;return&lt;/span&gt; mi.Invoke(&lt;span style="color:Blue;"&gt;null&lt;/span&gt;, &lt;span style="color:Blue;"&gt;new&lt;/span&gt; &lt;span style="color:Blue;"&gt;object&lt;/span&gt;[] { request, queryable }) &lt;span style="color:Blue;"&gt;as&lt;/span&gt; HttpResponseMessage;
    }

    &lt;span style="color:Blue;"&gt;private&lt;/span&gt; &lt;span style="color:Blue;"&gt;static&lt;/span&gt; HttpResponseMessage CreateQueryableResponseImpl&amp;lt;T&amp;gt;(HttpRequestMessage request, IQueryable&amp;lt;T&amp;gt; response)
    {
        &lt;span style="color:Blue;"&gt;return&lt;/span&gt; request.CreateResponse(response &lt;span style="color:Blue;"&gt;as&lt;/span&gt; IQueryable&amp;lt;T&amp;gt;);
    }
}
&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;5) Supporting only select.&lt;/h4&gt;&lt;div style="color:Black;background-color:White;"&gt;&lt;pre&gt;
[Queryable(AllowedQueryOptions = AllowedQueryOptions.Select)]
&lt;span style="color:Blue;"&gt;public&lt;/span&gt; IQueryable&amp;lt;Customer&amp;gt; GetCustomers()
{
    &lt;span style="color:Blue;"&gt;return&lt;/span&gt; _dbContext.Customers;
}
&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;6) Controlling maximum expansion depth.&lt;/h4&gt;&lt;div style="color:Black;background-color:White;"&gt;&lt;pre&gt;
[Queryable(MaxExpansionDepth = 1)]
&lt;span style="color:Blue;"&gt;public&lt;/span&gt; IQueryable&amp;lt;Customer&amp;gt; GetCustomers()
{
    &lt;span style="color:Blue;"&gt;return&lt;/span&gt; _dbContext.Customers;
}
&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;7) Controlling allowed expandable properties.&lt;/h4&gt;&lt;div style="color:Black;background-color:White;"&gt;&lt;pre&gt;
&lt;span style="color:Blue;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;"&gt;class&lt;/span&gt; CustomSelectExpandQueryValidator : SelectExpandQueryValidator
{
    &lt;span style="color:Blue;"&gt;private&lt;/span&gt; HashSet&amp;lt;&lt;span style="color:Blue;"&gt;string&lt;/span&gt;&amp;gt; _allowedExpandedProperties;

    &lt;span style="color:Blue;"&gt;public&lt;/span&gt; CustomSelectExpandQueryValidator(&lt;span style="color:Blue;"&gt;params&lt;/span&gt; &lt;span style="color:Blue;"&gt;string&lt;/span&gt;[] allowedExpandedProperties)
    {
        _allowedExpandedProperties = &lt;span style="color:Blue;"&gt;new&lt;/span&gt; HashSet&amp;lt;&lt;span style="color:Blue;"&gt;string&lt;/span&gt;&amp;gt;(allowedExpandedProperties);
    }

    &lt;span style="color:Blue;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;"&gt;override&lt;/span&gt; &lt;span style="color:Blue;"&gt;void&lt;/span&gt; Validate(SelectExpandQueryOption selectExpandQueryOption, ODataValidationSettings validationSettings)
    {
        &lt;span style="color:Blue;"&gt;base&lt;/span&gt;.Validate(selectExpandQueryOption, validationSettings);

        SelectExpandClause clause = selectExpandQueryOption.SelectExpandClause;
        &lt;span style="color:Blue;"&gt;foreach&lt;/span&gt; (ExpandItem item &lt;span style="color:Blue;"&gt;in&lt;/span&gt; clause.Expansion.ExpandItems)
        {
            NavigationPropertySegment navigationPropertySegment = item.PathToNavigationProperty.LastOrDefault() &lt;span style="color:Blue;"&gt;as&lt;/span&gt; NavigationPropertySegment;
            &lt;span style="color:Blue;"&gt;if&lt;/span&gt; (navigationPropertySegment != &lt;span style="color:Blue;"&gt;null&lt;/span&gt;)
            {
                &lt;span style="color:Blue;"&gt;string&lt;/span&gt; propertyName = navigationPropertySegment.NavigationProperty.Name;
                &lt;span style="color:Blue;"&gt;if&lt;/span&gt; (!_allowedExpandedProperties.Contains(propertyName))
                {
                    &lt;span style="color:Blue;"&gt;throw&lt;/span&gt; &lt;span style="color:Blue;"&gt;new&lt;/span&gt; ODataException(String.Format(&lt;span style="color:#A31515;"&gt;&amp;quot;Navigation property &amp;#39;{0}&amp;#39; cannot be expanded.&amp;quot;&lt;/span&gt;, propertyName));
                }
            }
        }
    }
}
&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;
&lt;h3&gt;Considerations and Open questions&lt;/h3&gt;There are several open questions that have to be discussed and concluded.
&lt;h4&gt;Support for other formatters&lt;/h4&gt;&lt;ol&gt;&lt;li&gt;Should we support $select with json and xml formatters? $expand is not important as these formatters expand by default. &lt;/li&gt;
&lt;li&gt;Should we change the behavior of these formatters to not expand by default if the incoming query contains a $expand clause?&lt;/li&gt;&lt;/ol&gt;
&lt;h4&gt;Query optimizations&lt;/h4&gt;1. Should $select be optimized? 
&lt;ul&gt;&lt;li&gt;$select is a shape changing query. From a web API perspective, this would mean that the ObjectContent&amp;lt;T&amp;gt; has to be reconstructed. What would happen to the content headers on the ObjectContent? Should we just do a content-negotiation again and say that any content-type headers set after the action finished and before the QueryableAttribute runs would be lost?&lt;/li&gt;
&lt;li&gt;An un-optimized $select would mean more memory allocation on the database.&lt;/li&gt;&lt;/ul&gt;
&lt;blockquote&gt;&lt;blockquote&gt;&lt;i&gt; design meeting@Mar 28&lt;sup&gt;th&lt;/sup&gt;: First cut, actions returning IQueryable will support $select and $expand as it won&amp;#39;t be a shape changing query anymore. $select will be optimized. &lt;/i&gt;&lt;/blockquote&gt;&lt;/blockquote&gt;
2. $expand has to be optimized.
&lt;ul&gt;&lt;li&gt;Without an optimized $expand no-one would ever use our $expand support unless they are building on top of in-memory IQueryable.&lt;/li&gt;
&lt;li&gt;How would the generated query look like? Should we just support EF or try be compatible with some other providers? (Scoping question).&lt;/li&gt;
&lt;li&gt;If we do it only for EF, what is the extensibility story for custom providers?&lt;/li&gt;&lt;/ul&gt;
&lt;blockquote&gt;&lt;blockquote&gt;&lt;i&gt; design meeting@Mar 28&lt;sup&gt;th&lt;/sup&gt;: work item: update with the queries &lt;/i&gt;&lt;/blockquote&gt;&lt;/blockquote&gt;
3. $select and $expand can be done on a single entity. In these cases there is no IQueryable returned by the action. How can we do query manipulation in this scenario? For example, http://server/Customers(42)?$select=Name maps to an web API action &lt;br /&gt;&lt;span class="codeInline"&gt; public Customer GetCustomer(int key). &lt;/span&gt;&lt;br /&gt;
&lt;h4&gt;PageSize for expanded feeds. &lt;/h4&gt;&lt;ol&gt;&lt;li&gt;How can one specify page size for expanded feeds? WCF DS has a per entity-set configuration knob for page size. Should we follow their model? &lt;/li&gt;&lt;/ol&gt;

&lt;h2&gt;Implementation details&lt;/h2&gt;The idea here is that a selection ($select) results in a LINQ .Select query using a wrapper class (kind of an static anonymous type) as the response. The wrapper class contains the properties that have to be included in the selection. For example, a $select involving a selection having one property uses a wrapper class that looks like this,&lt;br /&gt;&lt;div style="color:Black;background-color:White;"&gt;&lt;pre&gt;
&lt;span style="color:Blue;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;"&gt;class&lt;/span&gt; SelectExpandWrapper&amp;lt;TElement&amp;gt; 
{
    &lt;span style="color:Blue;"&gt;public&lt;/span&gt; PropertyContainer Container { &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;internal&lt;/span&gt; &lt;span style="color:Blue;"&gt;abstract&lt;/span&gt; &lt;span style="color:Blue;"&gt;class&lt;/span&gt; PropertyContainer
{
        &lt;span style="color:Blue;"&gt;public&lt;/span&gt; Dictionary&amp;lt;&lt;span style="color:Blue;"&gt;string&lt;/span&gt;, &lt;span style="color:Blue;"&gt;object&lt;/span&gt;&amp;gt; ToDictionary(&lt;span style="color:Blue;"&gt;bool&lt;/span&gt; includeAutoSelected = &lt;span style="color:Blue;"&gt;true&lt;/span&gt;)
}
&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;Also, we wanted to free the OData formatter from having to look at the $select and $expand options. To support that, the wrapper class should contain information about three things,
&lt;ol&gt;&lt;li&gt;what structural properties/navigation properties have to be serialized.&lt;/li&gt;
&lt;li&gt;what actions have to be included in the response.&lt;/li&gt;
&lt;li&gt;what navigation properties have to be expanded.&lt;/li&gt;&lt;/ol&gt;
&lt;br /&gt;To support that the wrapper should also implement the IEdmStructuredObject interface.&lt;br /&gt;&lt;pre&gt;public interface IEdmStructuredObject : IEdmObject
{
        bool TryGetValue(string propertyName, out object value);
}

public interface IEdmObject
{
        IEdmTypeReference GetEdmType();
}&lt;/pre&gt;&lt;br /&gt;The IEdmObject interface is just a way to get the EDM type name required for odata serialization and also provides a dynamic property accessor to separate the implementation of the Wrapper from the formatter. Users who don&amp;#39;t like our Wrapper implementation (geared towards EF and Linq2Objects) could consider doing their own implementations.&lt;br /&gt;
&lt;h4&gt;Generated queries&lt;/h4&gt;There are two things to consider here. &lt;br /&gt;
&lt;ol&gt;&lt;li&gt;OData formatter (in the default case), requires the key properties to generate navigation links. So, even if the client did not ask for key properties explicitly in the request, they have to be fetched from the database. We should probably have an extension point here, so that people who customize link generation can fetch extra properties if they want them for link generation.&lt;/li&gt;
&lt;li&gt;OData formatter requires the type name of the entity while writing responses. If we are getting a partial object from the database (wrapper class), we have to include the type name in the wrapper class. &lt;/li&gt;&lt;/ol&gt;
&lt;br /&gt;&lt;br /&gt;I am listing out the possible generated LINQ queries here for some scenarios for reference. The generated SQL queries (using EF) would be too complex in some cases. If you really want to look at them, refer to the following dump files,
&lt;ol&gt;&lt;li&gt;using Table per hierarchy strategy (TPH) which is code first default - &lt;a href="https://www.codeplex.com/Download?ProjectName=ASPNETWebStack&amp;DownloadId=647202"&gt;tph_dump.txt&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;using table per type strategy (TPT) - &lt;a href="https://www.codeplex.com/Download?ProjectName=ASPNETWebStack&amp;DownloadId=647201"&gt;tpt_dump.txt&lt;/a&gt;&lt;/li&gt;&lt;/ol&gt;
Also, if you are interested in playing around with the sample, I have the cs file &lt;a href="https://www.codeplex.com/Download?ProjectName=ASPNETWebStack&amp;DownloadId=647200"&gt;here&lt;/a&gt;.&lt;br /&gt;
&lt;h6&gt;simple $select&lt;/h6&gt;&lt;div style="color:Black;background-color:White;"&gt;&lt;pre&gt;
uri = &lt;span style="color:#A31515;"&gt;&amp;quot;~/Customers?$select=ID&amp;quot;&lt;/span&gt;;
query = customers.Select&amp;lt;Customer, Wrapper&amp;gt;(c =&amp;gt; &lt;span style="color:Blue;"&gt;new&lt;/span&gt; Wrapper&amp;lt;&lt;span style="color:Blue;"&gt;int&lt;/span&gt;&amp;gt;
{
    TypeName = c &lt;span style="color:Blue;"&gt;is&lt;/span&gt; SpecialCustomer ? typeNameSpecialCustomer : typeNameCustomer,
    Name1 = &lt;span style="color:#A31515;"&gt;&amp;quot;ID&amp;quot;&lt;/span&gt;,
    Value1 = c.ID
});
&lt;/pre&gt;&lt;/div&gt;Response:&lt;br /&gt;&lt;pre&gt;{
  &amp;quot;__type&amp;quot;: &amp;quot;NS.Customer&amp;quot;,
  &amp;quot;ID&amp;quot;: 1
}
{
  &amp;quot;__type&amp;quot;: &amp;quot;NS.SpecialCustomer&amp;quot;,
  &amp;quot;ID&amp;quot;: 2
}&lt;/pre&gt;
&lt;h6&gt;simple $expand&lt;/h6&gt;&lt;div style="color:Black;background-color:White;"&gt;&lt;pre&gt;
uri = &lt;span style="color:#A31515;"&gt;&amp;quot;~/Customers?$expand=Orders&amp;quot;&lt;/span&gt;;
query = customers.Select(c =&amp;gt; &lt;span style="color:Blue;"&gt;new&lt;/span&gt; SelectExpandWrapper&amp;lt;Customer&amp;gt;
{
    TypeName = c &lt;span style="color:Blue;"&gt;is&lt;/span&gt; SpecialCustomer ? typeNameSpecialCustomer : typeNameCustomer,
    Instance = c,
    PropertyContainer = &lt;span style="color:Blue;"&gt;new&lt;/span&gt; NamedProperty&amp;lt;Order&amp;gt;
    {
        Name = &lt;span style="color:#A31515;"&gt;&amp;quot;Orders&amp;quot;&lt;/span&gt;,
        Value = c.Orders.Select(o =&amp;gt; &lt;span style="color:Blue;"&gt;new&lt;/span&gt; SelectExpandWrapper
        {
            TypeName = o &lt;span style="color:Blue;"&gt;is&lt;/span&gt; SpecialOrder ? typeNameSpecialOrder : typeNameOrder,
            Instance = o
        })
    }
});
&lt;/pre&gt;&lt;/div&gt;Response:&lt;br /&gt;&lt;pre&gt;{
  &amp;quot;__type&amp;quot;: &amp;quot;NS.Customer&amp;quot;,
  &amp;quot;ID&amp;quot;: 1,
  &amp;quot;Name&amp;quot;: &amp;quot;Raghu&amp;quot;,
  &amp;quot;Orders&amp;quot;: [
    {
      &amp;quot;__type&amp;quot;: &amp;quot;NS.Order&amp;quot;,
      &amp;quot;ID&amp;quot;: 1,
      &amp;quot;Amount&amp;quot;: 400
    }
  ]
}
{
  &amp;quot;__type&amp;quot;: &amp;quot;NS.SpecialCustomer&amp;quot;,
  &amp;quot;ID&amp;quot;: 2,
  &amp;quot;Name&amp;quot;: &amp;quot;Ram&amp;quot;,
  &amp;quot;Orders&amp;quot;: [
    {
      &amp;quot;__type&amp;quot;: &amp;quot;NS.Order&amp;quot;,
      &amp;quot;ID&amp;quot;: 2,
      &amp;quot;Amount&amp;quot;: 1000
    }
  ]
}&lt;/pre&gt;
&lt;h6&gt;simple $select and $expand&lt;/h6&gt;&lt;div style="color:Black;background-color:White;"&gt;&lt;pre&gt;
uri = &lt;span style="color:#A31515;"&gt;&amp;quot;~/Customers?$select=Name,Orders&amp;amp;$expand=Orders&amp;quot;&lt;/span&gt;;
query = customers.Select(c =&amp;gt; &lt;span style="color:Blue;"&gt;new&lt;/span&gt; SelectExpandWrapper&amp;lt;Customer&amp;gt;
{
    TypeName = c &lt;span style="color:Blue;"&gt;is&lt;/span&gt; SpecialCustomer ? typeNameSpecialCustomer : typeNameCustomer,
    PropertyContainer = &lt;span style="color:Blue;"&gt;new&lt;/span&gt; NamedProperty&amp;lt;&lt;span style="color:Blue;"&gt;string&lt;/span&gt;&amp;gt; 
    {
        Name = &lt;span style="color:#A31515;"&gt;&amp;quot;Name&amp;quot;&lt;/span&gt;,
        Value = c.Name,
        Next = &lt;span style="color:Blue;"&gt;new&lt;/span&gt; NamedProperty&amp;lt;IEnumerable&amp;lt;Order&amp;gt;&amp;gt;
        {
            Name = &lt;span style="color:#A31515;"&gt;&amp;quot;Orders&amp;quot;&lt;/span&gt;,
            Value = c.Orders.Select&amp;lt;Order, Wrapper&amp;gt;(o =&amp;gt; &lt;span style="color:Blue;"&gt;new&lt;/span&gt; Wrapper
            {
                TypeName = o &lt;span style="color:Blue;"&gt;is&lt;/span&gt; SpecialOrder ? typeNameSpecialOrder : typeNameOrder
                Instance = o
            }
        })
    }
});
&lt;/pre&gt;&lt;/div&gt;&lt;pre&gt;Response:
{
  &amp;quot;__type&amp;quot;: &amp;quot;NS.Customer&amp;quot;,
  &amp;quot;Name&amp;quot;: &amp;quot;Raghu&amp;quot;,
  &amp;quot;Orders&amp;quot;: [
    {
      &amp;quot;__type&amp;quot;: &amp;quot;NS.Order&amp;quot;,
      &amp;quot;ID&amp;quot;: 1,
      &amp;quot;Amount&amp;quot;: 400
    }
  ]
}
{
  &amp;quot;__type&amp;quot;: &amp;quot;NS.SpecialCustomer&amp;quot;,
  &amp;quot;Name&amp;quot;: &amp;quot;Ram&amp;quot;,
  &amp;quot;Orders&amp;quot;: [
    {
      &amp;quot;__type&amp;quot;: &amp;quot;NS.Order&amp;quot;,
      &amp;quot;ID&amp;quot;: 2,
      &amp;quot;Amount&amp;quot;: 1000
    }
  ]
}&lt;/pre&gt;&lt;h6&gt;selecting properties from expanded results&lt;/h6&gt;&lt;div style="color:Black;background-color:White;"&gt;&lt;pre&gt;
uri = &lt;span style="color:#A31515;"&gt;&amp;quot;~/Customers?$select=Name,Orders/ID,Orders/Amount&amp;amp;$expand=Orders&amp;quot;&lt;/span&gt;;
query = customers.Select(c =&amp;gt; &lt;span style="color:Blue;"&gt;new&lt;/span&gt; SelectExpandWrapper&amp;lt;Customer&amp;gt;
{
    TypeName = c &lt;span style="color:Blue;"&gt;is&lt;/span&gt; SpecialCustomer ? typeNameSpecialCustomer : typeNameCustomer,
    PropertyContainer = &lt;span style="color:Blue;"&gt;new&lt;/span&gt; NamedProperty&amp;lt;&lt;span style="color:Blue;"&gt;string&lt;/span&gt;&amp;gt;
    {
        Name = &lt;span style="color:#A31515;"&gt;&amp;quot;Name&amp;quot;&lt;/span&gt;,
        Value = c.Name,
        Next = &lt;span style="color:Blue;"&gt;new&lt;/span&gt; NamedProperty&amp;lt;IEnumerable&amp;lt;SelectExpandWrapper&amp;lt;Order&amp;gt;&amp;gt;&amp;gt;
        {
            Name = &lt;span style="color:#A31515;"&gt;&amp;quot;Orders&amp;quot;&lt;/span&gt;,
            Value = c.Orders(o =&amp;gt; &lt;span style="color:Blue;"&gt;new&lt;/span&gt; SelectExpandWrapper&amp;lt;Order&amp;gt;
            {
                TypeName = o &lt;span style="color:Blue;"&gt;is&lt;/span&gt; SpecialOrder ? typeNameSpecialOrder : typeNameOrder,
                PropertyContainer = &lt;span style="color:Blue;"&gt;new&lt;/span&gt; NamedProperty&amp;lt;&lt;span style="color:Blue;"&gt;int&lt;/span&gt;&amp;gt;
                {
                    Name = &lt;span style="color:#A31515;"&gt;&amp;quot;ID&amp;quot;&lt;/span&gt;,
                    Value = o.ID,
                    Next = &lt;span style="color:Blue;"&gt;new&lt;/span&gt; NamedProperty&amp;lt;&lt;span style="color:Blue;"&gt;int&lt;/span&gt;&amp;gt; 
                    {
                        Name = &lt;span style="color:#A31515;"&gt;&amp;quot;Amount&amp;quot;&lt;/span&gt;,
                        Value = o.Amount
                    }
                }
            }
    })
});
&lt;/pre&gt;&lt;/div&gt;Response:&lt;br /&gt;&lt;pre&gt;{
  &amp;quot;__type&amp;quot;: &amp;quot;NS.Customer&amp;quot;,
  &amp;quot;Name&amp;quot;: &amp;quot;Raghu&amp;quot;,
  &amp;quot;Orders&amp;quot;: [
    {
      &amp;quot;__type&amp;quot;: &amp;quot;NS.Order&amp;quot;,
      &amp;quot;ID&amp;quot;: 1,
      &amp;quot;Amount&amp;quot;: 400
    }
  ]
}
{
  &amp;quot;__type&amp;quot;: &amp;quot;NS.SpecialCustomer&amp;quot;,
  &amp;quot;Name&amp;quot;: &amp;quot;Ram&amp;quot;,
  &amp;quot;Orders&amp;quot;: [
    {
      &amp;quot;__type&amp;quot;: &amp;quot;NS.Order&amp;quot;,
      &amp;quot;ID&amp;quot;: 2,
      &amp;quot;Amount&amp;quot;: 1000
    }
  ]
}&lt;/pre&gt;
&lt;h6&gt;expanding properties on derived types&lt;/h6&gt;&lt;div style="color:Black;background-color:White;"&gt;&lt;pre&gt;
uri = &lt;span style="color:#A31515;"&gt;&amp;quot;~/Customers?$expand=NS.SpecialCustomer/SpecialOrders&amp;quot;&lt;/span&gt;;
query = customers.Select(c =&amp;gt; &lt;span style="color:Blue;"&gt;new&lt;/span&gt; SelectExpandWrapper&amp;lt;Customer&amp;gt;
{
    TypeName = c &lt;span style="color:Blue;"&gt;is&lt;/span&gt; SpecialCustomer ? typeNameSpecialCustomer : typeNameCustomer,
    Instance = c,
    PropertyContainer = &lt;span style="color:Blue;"&gt;new&lt;/span&gt; NamedProperty&amp;lt;SpecialCustomer&amp;gt;
    {
        Name = c &lt;span style="color:Blue;"&gt;is&lt;/span&gt; SpecialCustomer ? &lt;span style="color:#A31515;"&gt;&amp;quot;SpecialOrders&amp;quot;&lt;/span&gt; : &lt;span style="color:Blue;"&gt;null&lt;/span&gt;,
        Value = (c &lt;span style="color:Blue;"&gt;as&lt;/span&gt; SpecialCustomer).Orders.Select(o =&amp;gt; &lt;span style="color:Blue;"&gt;new&lt;/span&gt; SelectExpandWrapper&amp;lt;Order&amp;gt;
        {
            TypeName = o &lt;span style="color:Blue;"&gt;is&lt;/span&gt; SpecialOrder ? typeNameSpecialOrder : typeNameOrder,
            Instance = o
        }) &lt;span style="color:Green;"&gt;//requires null propagation. also don&amp;#39;t confuse null and non-existence&lt;/span&gt;
    }
});
&lt;/pre&gt;&lt;/div&gt;Response:&lt;br /&gt;&lt;pre&gt;{
  &amp;quot;__type&amp;quot;: &amp;quot;NS.Customer&amp;quot;,
  &amp;quot;ID&amp;quot;: 1,
  &amp;quot;Name&amp;quot;: &amp;quot;Raghu&amp;quot;
}
{
  &amp;quot;__type&amp;quot;: &amp;quot;NS.SpecialCustomer&amp;quot;,
  &amp;quot;ID&amp;quot;: 2,
  &amp;quot;Name&amp;quot;: &amp;quot;Ram&amp;quot;,
  &amp;quot;SpecialOrders&amp;quot;: [
    {
      &amp;quot;__type&amp;quot;: &amp;quot;NS.Order&amp;quot;,
      &amp;quot;ID&amp;quot;: 2,
      &amp;quot;Amount&amp;quot;: 1000
    }
  ]
}&lt;/pre&gt;
&lt;h6&gt;selecting properties on derived types&lt;/h6&gt;&lt;div style="color:Black;background-color:White;"&gt;&lt;pre&gt;
uri = &lt;span style="color:#A31515;"&gt;&amp;quot;~/Customers?$select=Name,NS.SpecialCustomer/SpecialCustomerProperty&amp;quot;&lt;/span&gt;;
query = customers.Select(c =&amp;gt; &lt;span style="color:Blue;"&gt;new&lt;/span&gt; SelectExpandWrapper&amp;lt;Customer&amp;gt;
{
    TypeName = c &lt;span style="color:Blue;"&gt;is&lt;/span&gt; SpecialCustomer ? typeNameSpecialCustomer : typeNameCustomer,
    PropertyContainer = &lt;span style="color:Blue;"&gt;new&lt;/span&gt; NamedProperty&amp;lt;&lt;span style="color:Blue;"&gt;string&lt;/span&gt;&amp;gt;
    {
        Name = &lt;span style="color:#A31515;"&gt;&amp;quot;Name&amp;quot;&lt;/span&gt;,
        Value = c.Name,
        Next = &lt;span style="color:Blue;"&gt;new&lt;/span&gt; PropertyContainer&amp;lt;SpecialCustomer&amp;gt;
        {
            Name = c &lt;span style="color:Blue;"&gt;is&lt;/span&gt; SpecialCustomer ? &lt;span style="color:#A31515;"&gt;&amp;quot;SpecialCustomerProperty&amp;quot;&lt;/span&gt; : &lt;span style="color:Blue;"&gt;null&lt;/span&gt;,
            Value = (c &lt;span style="color:Blue;"&gt;as&lt;/span&gt; SpecialCustomer).SpecialCustomerProperty &lt;span style="color:Green;"&gt;// requires null propagation.&lt;/span&gt;
        }
    }
});
&lt;/pre&gt;&lt;/div&gt;Response:&lt;br /&gt;&lt;pre&gt;{
  &amp;quot;__type&amp;quot;: &amp;quot;NS.Customer&amp;quot;,
  &amp;quot;Name&amp;quot;: &amp;quot;Raghu&amp;quot;
}
{
  &amp;quot;__type&amp;quot;: &amp;quot;NS.SpecialCustomer&amp;quot;,
  &amp;quot;Name&amp;quot;: &amp;quot;Ram&amp;quot;,
  &amp;quot;SpecialCustomerProperty&amp;quot;: 42
}&lt;/pre&gt;
&lt;h6&gt;expanding properties on expanded derived types&lt;/h6&gt;&lt;div style="color:Black;background-color:White;"&gt;&lt;pre&gt;
uri = &lt;span style="color:#A31515;"&gt;&amp;quot;~/Customers?$select=Name&amp;amp;$expand=Orders,Orders/NS.SpecialOrder/SpecialCustomer&amp;quot;&lt;/span&gt;;
query = customers.Select&amp;lt;Customer, Wrapper&amp;gt;(c =&amp;gt; &lt;span style="color:Blue;"&gt;new&lt;/span&gt; SelectExpandWrapper&amp;lt;Customer&amp;gt;
{
    TypeName = c &lt;span style="color:Blue;"&gt;is&lt;/span&gt; SpecialCustomer ? typeNameSpecialCustomer : typeNameCustomer,
    PropertyContainer = &lt;span style="color:Blue;"&gt;new&lt;/span&gt; NamedProperty&amp;lt;&lt;span style="color:Blue;"&gt;string&lt;/span&gt;&amp;gt;
    {
        Name = &lt;span style="color:#A31515;"&gt;&amp;quot;Name&amp;quot;&lt;/span&gt;,
        Value = c.Name,
        Next = &lt;span style="color:Blue;"&gt;new&lt;/span&gt; NamedProperty&amp;lt;IEnumerable&amp;lt;SelectExpandWrapper&amp;lt;Order&amp;gt;&amp;gt;&amp;gt;
        {
            Name = &lt;span style="color:#A31515;"&gt;&amp;quot;Orders&amp;quot;&lt;/span&gt;,
            Value = c.Orders.Select(o =&amp;gt; &lt;span style="color:Blue;"&gt;new&lt;/span&gt; SelectExpandWrapper&amp;lt;Order&amp;gt;
            {
                Instance = o,
                Name = o &lt;span style="color:Blue;"&gt;is&lt;/span&gt; SpecialOrder ? &lt;span style="color:#A31515;"&gt;&amp;quot;SpecialCustomer&amp;quot;&lt;/span&gt; : &lt;span style="color:Blue;"&gt;null&lt;/span&gt;, &lt;span style="color:Green;"&gt;// optional property&lt;/span&gt;
                Value = &lt;span style="color:Blue;"&gt;new&lt;/span&gt; Wrapper
                {
                    Instance = (o &lt;span style="color:Blue;"&gt;as&lt;/span&gt; SpecialOrder).SpecialCustomer
                }
            }
        }
    })
});
&lt;/pre&gt;&lt;/div&gt;Response:&lt;br /&gt;&lt;pre&gt;{
  &amp;quot;__type&amp;quot;: &amp;quot;NS.Customer&amp;quot;,
  &amp;quot;Name&amp;quot;: &amp;quot;Raghu&amp;quot;,
  &amp;quot;Orders&amp;quot;: [
    {
      &amp;quot;__type&amp;quot;: null,
      &amp;quot;ID&amp;quot;: 1,
      &amp;quot;Amount&amp;quot;: 400
    }
  ]
}
{
  &amp;quot;__type&amp;quot;: &amp;quot;NS.SpecialCustomer&amp;quot;,
  &amp;quot;Name&amp;quot;: &amp;quot;Ram&amp;quot;,
  &amp;quot;Orders&amp;quot;: [
    {
      &amp;quot;__type&amp;quot;: null,
      &amp;quot;ID&amp;quot;: 2,
      &amp;quot;Amount&amp;quot;: 1000,
      &amp;quot;SpecialCustomer&amp;quot;: {
        &amp;quot;__type&amp;quot;: &amp;quot;NS.SpecialCustomer&amp;quot;,
        &amp;quot;ID&amp;quot;: 2,
        &amp;quot;Name&amp;quot;: &amp;quot;Ram&amp;quot;,
        &amp;quot;SpecialCustomerProperty&amp;quot;: 42
      }
    }
  ]
}&lt;/pre&gt;&lt;/div&gt;&lt;div class="ClearBoth"&gt;&lt;/div&gt;</description><author>raghuramn</author><pubDate>Thu, 09 May 2013 21:04:33 GMT</pubDate><guid isPermaLink="false">Updated Wiki: $select and $expand support 20130509090433P</guid></item><item><title>Updated Wiki: $select and $expand support</title><link>https://aspnetwebstack.codeplex.com/wikipage?title=$select and $expand support&amp;version=26</link><description>&lt;div class="wikidoc"&gt;&lt;h1&gt;$select and $expand support&lt;/h1&gt;&lt;hr /&gt;
The $select system query option allows clients to requests a limited set of information for each entity or complex type identified by the ResourcePath and other System Query Options like $filter, $top, $skip etc. The $select query option is often used in conjunction with the $expand query option, to first increase the scope of the resource graph returned ($expand) and then selectively prune that resource graph ($select).&lt;br /&gt;&lt;br /&gt;The $expand system query option allows clients to request related resources when a resource that satisfies a particular request is retrieved.&lt;br /&gt;&lt;br /&gt;The following model would be used for the rest of the scenarios,&lt;br /&gt;&lt;br /&gt;&lt;div style="color:Black;background-color:White;"&gt;&lt;pre&gt;
&lt;span style="color:Blue;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;"&gt;class&lt;/span&gt; Customer
{
    &lt;span style="color:Blue;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;"&gt;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&lt;/span&gt; &lt;span style="color:Blue;"&gt;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:Blue;"&gt;virtual&lt;/span&gt; ICollection&amp;lt;Order&amp;gt; Orders { &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:Blue;"&gt;class&lt;/span&gt; SpecialCustomer : Customer
{
    &lt;span style="color:Blue;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;"&gt;int&lt;/span&gt; SpecialCustomerProperty { &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:Blue;"&gt;virtual&lt;/span&gt; ICollection&amp;lt;SpecialOrder&amp;gt; SpecialOrders { &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:Blue;"&gt;class&lt;/span&gt; Order
{
    &lt;span style="color:Blue;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;"&gt;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&lt;/span&gt; &lt;span style="color:Blue;"&gt;int&lt;/span&gt; Amount { &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; Customer Customer { &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:Blue;"&gt;class&lt;/span&gt; SpecialOrder : Order
{
    &lt;span style="color:Blue;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;"&gt;int&lt;/span&gt; SpecialOrderProperty { &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:Blue;"&gt;virtual&lt;/span&gt; SpecialCustomer SpecialCustomer { &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;private&lt;/span&gt; &lt;span style="color:Blue;"&gt;static&lt;/span&gt; IEdmModel GetModel()
{
    ODataConventionModelBuilder builder = &lt;span style="color:Blue;"&gt;new&lt;/span&gt; ODataConventionModelBuilder();
    builder.EntitySet&amp;lt;Customer&amp;gt;(&lt;span style="color:#A31515;"&gt;&amp;quot;Customers&amp;quot;&lt;/span&gt;);
    builder.EntitySet&amp;lt;Order&amp;gt;(&lt;span style="color:#A31515;"&gt;&amp;quot;Orders&amp;quot;&lt;/span&gt;);
    &lt;span style="color:Blue;"&gt;return&lt;/span&gt; builder.GetEdmModel();
}
&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;For example, assuming that a service exposes two entity sets ‘Customers’ and ‘Orders’ and a customer has 1..* (one-to-many) relationship with order, the following URL’s are valid,&lt;br /&gt;
&lt;h3&gt;Supported scenarios&lt;/h3&gt;&lt;a href="http://server/Customers?$select=Id,Name"&gt;http://server/Customers?$select=Id,Name&lt;/a&gt; &lt;br /&gt;Response should contain only the properties Id and Name for each customer. Navigation link for the property Orders must not be present in the response.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://server/Customers?$expand=Orders"&gt;http://server/Customers?$expand=Orders&lt;/a&gt; &lt;br /&gt;Response should contain all the properties of Customer for each customer. It should also contain the expanded Orders for each customer along with the navigation link (depending on the metadata level though). The expanded Orders should contain all structural properties of Orders and navigation link for each navigation property on Order.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://server/Customers?$select=Id,Name,Orders&amp;amp;$expand=Orders"&gt;http://server/Customers?$select=Id,Name,Orders&amp;amp;$expand=Orders&lt;/a&gt; &lt;br /&gt;Response should contain properties Id and Name for each customer and expanded Orders. Each expanded Order should contain all the structural properties of order and a navigation link for each navigation property of order.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://server/Customers?$select=Orders/Id&amp;amp;$expand=Orders"&gt;http://server/Customers?$select=Orders/Id&amp;amp;$expand=Orders&lt;/a&gt; &lt;br /&gt;Selection on an expanded property.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://server/Customers?$select=Id,NS.SpecialCustomer/SpecialId"&gt;http://server/Customers?$select=Id,NS.SpecialCustomer/SpecialId&lt;/a&gt; &lt;br /&gt;Response should contain Id property for each customer and also includes the SpecialId property for each special customer. ODataLib uri parser doesn’t support this yet.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://server/Customers?$expand=NS.SpecialCustomer/SpecialOrder"&gt;http://server/Customers?$expand=NS.SpecialCustomer/SpecialOrder&lt;/a&gt; &lt;br /&gt;Response should contain all structural properties and expand the SpecialOrder property for each special customer. A normal customer would have his navigation links as deferred content in the response. ODataLib uri parser doesn’t support this yet.&lt;br /&gt;&lt;br /&gt;
&lt;h3&gt;Not supported scenarios&lt;/h3&gt;&lt;a href="http://server/Customers(42)/Address?$select=City"&gt;http://server/Customers(42)/Address?$select=City&lt;/a&gt;&lt;br /&gt;Selections of complex types is not supported. (OData V4 might have support for it though)&lt;br /&gt;
&lt;h3&gt;Samples&lt;/h3&gt;
&lt;h4&gt;1) Supporting $select and $expand on collections through QueryableAttribute.&lt;/h4&gt;&lt;div style="color:Black;background-color:White;"&gt;&lt;pre&gt;
[Queryable]
&lt;span style="color:Blue;"&gt;public&lt;/span&gt; IQueryable&amp;lt;Customer&amp;gt; GetCustomers()
{
    &lt;span style="color:Blue;"&gt;return&lt;/span&gt; _dbContext.Customers;
}
&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;2) Supporting $select and $expand on single entities through QueryableAttribute.&lt;/h4&gt;&lt;div style="color:Black;background-color:White;"&gt;&lt;pre&gt;
[Queryable]
&lt;span style="color:Blue;"&gt;public&lt;/span&gt; SingleResult&amp;lt;Customer&amp;gt; GetCustomer(&lt;span style="color:Blue;"&gt;int&lt;/span&gt; id)
{
    &lt;span style="color:Blue;"&gt;return&lt;/span&gt; SingleResult.Create(_dbContext.Customers.Where(c =&amp;gt; c.ID == id);
}
&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;3) Supporting $select and $expand on single entities when you don&amp;#39;t have a db context (Linq2Objects).&lt;/h4&gt;&lt;div style="color:Black;background-color:White;"&gt;&lt;pre&gt;
[Queryable]
&lt;span style="color:Blue;"&gt;public&lt;/span&gt; Customer GetCustomer(&lt;span style="color:Blue;"&gt;int&lt;/span&gt; id)
{
    &lt;span style="color:Blue;"&gt;return&lt;/span&gt; _repository.Find(id);
}
&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;4) Supporting only select.&lt;/h4&gt;&lt;div style="color:Black;background-color:White;"&gt;&lt;pre&gt;
[Queryable(AllowedQueryOptions = AllowedQueryOptions.Select)]
&lt;span style="color:Blue;"&gt;public&lt;/span&gt; IQueryable&amp;lt;Customer&amp;gt; GetCustomers()
{
    &lt;span style="color:Blue;"&gt;return&lt;/span&gt; _dbContext.Customers;
}
&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;5) Controlling maximum expansion depth.&lt;/h4&gt;&lt;div style="color:Black;background-color:White;"&gt;&lt;pre&gt;
[Queryable(MaxExpansionDepth = 1)]
&lt;span style="color:Blue;"&gt;public&lt;/span&gt; IQueryable&amp;lt;Customer&amp;gt; GetCustomers()
{
    &lt;span style="color:Blue;"&gt;return&lt;/span&gt; _dbContext.Customers;
}
&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;6) Controlling allowed expandable properties.&lt;/h4&gt;&lt;div style="color:Black;background-color:White;"&gt;&lt;pre&gt;
&lt;span style="color:Blue;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;"&gt;class&lt;/span&gt; CustomSelectExpandQueryValidator : SelectExpandQueryValidator
{
    &lt;span style="color:Blue;"&gt;private&lt;/span&gt; HashSet&amp;lt;&lt;span style="color:Blue;"&gt;string&lt;/span&gt;&amp;gt; _allowedExpandedProperties;

    &lt;span style="color:Blue;"&gt;public&lt;/span&gt; CustomSelectExpandQueryValidator(&lt;span style="color:Blue;"&gt;params&lt;/span&gt; &lt;span style="color:Blue;"&gt;string&lt;/span&gt;[] allowedExpandedProperties)
    {
        _allowedExpandedProperties = &lt;span style="color:Blue;"&gt;new&lt;/span&gt; HashSet&amp;lt;&lt;span style="color:Blue;"&gt;string&lt;/span&gt;&amp;gt;(allowedExpandedProperties);
    }

    &lt;span style="color:Blue;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;"&gt;override&lt;/span&gt; &lt;span style="color:Blue;"&gt;void&lt;/span&gt; Validate(SelectExpandQueryOption selectExpandQueryOption, ODataValidationSettings validationSettings)
    {
        &lt;span style="color:Blue;"&gt;base&lt;/span&gt;.Validate(selectExpandQueryOption, validationSettings);

        SelectExpandClause clause = selectExpandQueryOption.SelectExpandClause;
        &lt;span style="color:Blue;"&gt;foreach&lt;/span&gt; (ExpandItem item &lt;span style="color:Blue;"&gt;in&lt;/span&gt; clause.Expansion.ExpandItems)
        {
            NavigationPropertySegment navigationPropertySegment = item.PathToNavigationProperty.LastOrDefault() &lt;span style="color:Blue;"&gt;as&lt;/span&gt; NavigationPropertySegment;
            &lt;span style="color:Blue;"&gt;if&lt;/span&gt; (navigationPropertySegment != &lt;span style="color:Blue;"&gt;null&lt;/span&gt;)
            {
                &lt;span style="color:Blue;"&gt;string&lt;/span&gt; propertyName = navigationPropertySegment.NavigationProperty.Name;
                &lt;span style="color:Blue;"&gt;if&lt;/span&gt; (!_allowedExpandedProperties.Contains(propertyName))
                {
                    &lt;span style="color:Blue;"&gt;throw&lt;/span&gt; &lt;span style="color:Blue;"&gt;new&lt;/span&gt; ODataException(String.Format(&lt;span style="color:#A31515;"&gt;&amp;quot;Navigation property &amp;#39;{0}&amp;#39; cannot be expanded.&amp;quot;&lt;/span&gt;, propertyName));
                }
            }
        }
    }
}
&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;
&lt;h3&gt;Considerations and Open questions&lt;/h3&gt;There are several open questions that have to be discussed and concluded.
&lt;h4&gt;Support for other formatters&lt;/h4&gt;&lt;ol&gt;&lt;li&gt;Should we support $select with json and xml formatters? $expand is not important as these formatters expand by default. &lt;/li&gt;
&lt;li&gt;Should we change the behavior of these formatters to not expand by default if the incoming query contains a $expand clause?&lt;/li&gt;&lt;/ol&gt;
&lt;h4&gt;Query optimizations&lt;/h4&gt;1. Should $select be optimized? 
&lt;ul&gt;&lt;li&gt;$select is a shape changing query. From a web API perspective, this would mean that the ObjectContent&amp;lt;T&amp;gt; has to be reconstructed. What would happen to the content headers on the ObjectContent? Should we just do a content-negotiation again and say that any content-type headers set after the action finished and before the QueryableAttribute runs would be lost?&lt;/li&gt;
&lt;li&gt;An un-optimized $select would mean more memory allocation on the database.&lt;/li&gt;&lt;/ul&gt;
&lt;blockquote&gt;&lt;blockquote&gt;&lt;i&gt; design meeting@Mar 28&lt;sup&gt;th&lt;/sup&gt;: First cut, actions returning IQueryable will support $select and $expand as it won&amp;#39;t be a shape changing query anymore. $select will be optimized. &lt;/i&gt;&lt;/blockquote&gt;&lt;/blockquote&gt;
2. $expand has to be optimized.
&lt;ul&gt;&lt;li&gt;Without an optimized $expand no-one would ever use our $expand support unless they are building on top of in-memory IQueryable.&lt;/li&gt;
&lt;li&gt;How would the generated query look like? Should we just support EF or try be compatible with some other providers? (Scoping question).&lt;/li&gt;
&lt;li&gt;If we do it only for EF, what is the extensibility story for custom providers?&lt;/li&gt;&lt;/ul&gt;
&lt;blockquote&gt;&lt;blockquote&gt;&lt;i&gt; design meeting@Mar 28&lt;sup&gt;th&lt;/sup&gt;: work item: update with the queries &lt;/i&gt;&lt;/blockquote&gt;&lt;/blockquote&gt;
3. $select and $expand can be done on a single entity. In these cases there is no IQueryable returned by the action. How can we do query manipulation in this scenario? For example, http://server/Customers(42)?$select=Name maps to an web API action &lt;br /&gt;&lt;span class="codeInline"&gt; public Customer GetCustomer(int key). &lt;/span&gt;&lt;br /&gt;
&lt;h4&gt;PageSize for expanded feeds. &lt;/h4&gt;&lt;ol&gt;&lt;li&gt;How can one specify page size for expanded feeds? WCF DS has a per entity-set configuration knob for page size. Should we follow their model? &lt;/li&gt;&lt;/ol&gt;

&lt;h2&gt;Implementation details&lt;/h2&gt;The idea here is that a selection ($select) results in a LINQ .Select query using a wrapper class (kind of an static anonymous type) as the response. The wrapper class contains the properties that have to be included in the selection. For example, a $select involving a selection having one property uses a wrapper class that looks like this,&lt;br /&gt;&lt;div style="color:Black;background-color:White;"&gt;&lt;pre&gt;
&lt;span style="color:Blue;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;"&gt;class&lt;/span&gt; SelectExpandWrapper&amp;lt;TElement&amp;gt; 
{
    &lt;span style="color:Blue;"&gt;public&lt;/span&gt; PropertyContainer Container { &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;internal&lt;/span&gt; &lt;span style="color:Blue;"&gt;abstract&lt;/span&gt; &lt;span style="color:Blue;"&gt;class&lt;/span&gt; PropertyContainer
{
        &lt;span style="color:Blue;"&gt;public&lt;/span&gt; Dictionary&amp;lt;&lt;span style="color:Blue;"&gt;string&lt;/span&gt;, &lt;span style="color:Blue;"&gt;object&lt;/span&gt;&amp;gt; ToDictionary(&lt;span style="color:Blue;"&gt;bool&lt;/span&gt; includeAutoSelected = &lt;span style="color:Blue;"&gt;true&lt;/span&gt;)
}
&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;Also, we wanted to free the OData formatter from having to look at the $select and $expand options. To support that, the wrapper class should contain information about three things,
&lt;ol&gt;&lt;li&gt;what structural properties/navigation properties have to be serialized.&lt;/li&gt;
&lt;li&gt;what actions have to be included in the response.&lt;/li&gt;
&lt;li&gt;what navigation properties have to be expanded.&lt;/li&gt;&lt;/ol&gt;
&lt;br /&gt;To support that the wrapper should also implement the IEdmStructuredObject interface.&lt;br /&gt;&lt;pre&gt;public interface IEdmStructuredObject : IEdmObject
{
        bool TryGetValue(string propertyName, out object value);
}

public interface IEdmObject
{
        IEdmTypeReference GetEdmType();
}&lt;/pre&gt;&lt;br /&gt;The IEdmObject interface is just a way to get the EDM type name required for odata serialization and also provides a dynamic property accessor to separate the implementation of the Wrapper from the formatter. Users who don&amp;#39;t like our Wrapper implementation (geared towards EF and Linq2Objects) could consider doing their own implementations.&lt;br /&gt;
&lt;h4&gt;Generated queries&lt;/h4&gt;There are two things to consider here. &lt;br /&gt;
&lt;ol&gt;&lt;li&gt;OData formatter (in the default case), requires the key properties to generate navigation links. So, even if the client did not ask for key properties explicitly in the request, they have to be fetched from the database. We should probably have an extension point here, so that people who customize link generation can fetch extra properties if they want them for link generation.&lt;/li&gt;
&lt;li&gt;OData formatter requires the type name of the entity while writing responses. If we are getting a partial object from the database (wrapper class), we have to include the type name in the wrapper class. &lt;/li&gt;&lt;/ol&gt;
&lt;br /&gt;&lt;br /&gt;I am listing out the possible generated LINQ queries here for some scenarios for reference. The generated SQL queries (using EF) would be too complex in some cases. If you really want to look at them, refer to the following dump files,
&lt;ol&gt;&lt;li&gt;using Table per hierarchy strategy (TPH) which is code first default - &lt;a href="https://www.codeplex.com/Download?ProjectName=ASPNETWebStack&amp;DownloadId=647202"&gt;tph_dump.txt&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;using table per type strategy (TPT) - &lt;a href="https://www.codeplex.com/Download?ProjectName=ASPNETWebStack&amp;DownloadId=647201"&gt;tpt_dump.txt&lt;/a&gt;&lt;/li&gt;&lt;/ol&gt;
Also, if you are interested in playing around with the sample, I have the cs file &lt;a href="https://www.codeplex.com/Download?ProjectName=ASPNETWebStack&amp;DownloadId=647200"&gt;here&lt;/a&gt;.&lt;br /&gt;
&lt;h6&gt;simple $select&lt;/h6&gt;&lt;div style="color:Black;background-color:White;"&gt;&lt;pre&gt;
uri = &lt;span style="color:#A31515;"&gt;&amp;quot;~/Customers?$select=ID&amp;quot;&lt;/span&gt;;
query = customers.Select&amp;lt;Customer, Wrapper&amp;gt;(c =&amp;gt; &lt;span style="color:Blue;"&gt;new&lt;/span&gt; Wrapper&amp;lt;&lt;span style="color:Blue;"&gt;int&lt;/span&gt;&amp;gt;
{
    TypeName = c &lt;span style="color:Blue;"&gt;is&lt;/span&gt; SpecialCustomer ? typeNameSpecialCustomer : typeNameCustomer,
    Name1 = &lt;span style="color:#A31515;"&gt;&amp;quot;ID&amp;quot;&lt;/span&gt;,
    Value1 = c.ID
});
&lt;/pre&gt;&lt;/div&gt;Response:&lt;br /&gt;&lt;pre&gt;{
  &amp;quot;__type&amp;quot;: &amp;quot;NS.Customer&amp;quot;,
  &amp;quot;ID&amp;quot;: 1
}
{
  &amp;quot;__type&amp;quot;: &amp;quot;NS.SpecialCustomer&amp;quot;,
  &amp;quot;ID&amp;quot;: 2
}&lt;/pre&gt;
&lt;h6&gt;simple $expand&lt;/h6&gt;&lt;div style="color:Black;background-color:White;"&gt;&lt;pre&gt;
uri = &lt;span style="color:#A31515;"&gt;&amp;quot;~/Customers?$expand=Orders&amp;quot;&lt;/span&gt;;
query = customers.Select(c =&amp;gt; &lt;span style="color:Blue;"&gt;new&lt;/span&gt; SelectExpandWrapper&amp;lt;Customer&amp;gt;
{
    TypeName = c &lt;span style="color:Blue;"&gt;is&lt;/span&gt; SpecialCustomer ? typeNameSpecialCustomer : typeNameCustomer,
    Instance = c,
    PropertyContainer = &lt;span style="color:Blue;"&gt;new&lt;/span&gt; NamedProperty&amp;lt;Order&amp;gt;
    {
        Name = &lt;span style="color:#A31515;"&gt;&amp;quot;Orders&amp;quot;&lt;/span&gt;,
        Value = c.Orders.Select(o =&amp;gt; &lt;span style="color:Blue;"&gt;new&lt;/span&gt; SelectExpandWrapper
        {
            TypeName = o &lt;span style="color:Blue;"&gt;is&lt;/span&gt; SpecialOrder ? typeNameSpecialOrder : typeNameOrder,
            Instance = o
        })
    }
});
&lt;/pre&gt;&lt;/div&gt;Response:&lt;br /&gt;&lt;pre&gt;{
  &amp;quot;__type&amp;quot;: &amp;quot;NS.Customer&amp;quot;,
  &amp;quot;ID&amp;quot;: 1,
  &amp;quot;Name&amp;quot;: &amp;quot;Raghu&amp;quot;,
  &amp;quot;Orders&amp;quot;: [
    {
      &amp;quot;__type&amp;quot;: &amp;quot;NS.Order&amp;quot;,
      &amp;quot;ID&amp;quot;: 1,
      &amp;quot;Amount&amp;quot;: 400
    }
  ]
}
{
  &amp;quot;__type&amp;quot;: &amp;quot;NS.SpecialCustomer&amp;quot;,
  &amp;quot;ID&amp;quot;: 2,
  &amp;quot;Name&amp;quot;: &amp;quot;Ram&amp;quot;,
  &amp;quot;Orders&amp;quot;: [
    {
      &amp;quot;__type&amp;quot;: &amp;quot;NS.Order&amp;quot;,
      &amp;quot;ID&amp;quot;: 2,
      &amp;quot;Amount&amp;quot;: 1000
    }
  ]
}&lt;/pre&gt;
&lt;h6&gt;simple $select and $expand&lt;/h6&gt;&lt;div style="color:Black;background-color:White;"&gt;&lt;pre&gt;
uri = &lt;span style="color:#A31515;"&gt;&amp;quot;~/Customers?$select=Name,Orders&amp;amp;$expand=Orders&amp;quot;&lt;/span&gt;;
query = customers.Select(c =&amp;gt; &lt;span style="color:Blue;"&gt;new&lt;/span&gt; SelectExpandWrapper&amp;lt;Customer&amp;gt;
{
    TypeName = c &lt;span style="color:Blue;"&gt;is&lt;/span&gt; SpecialCustomer ? typeNameSpecialCustomer : typeNameCustomer,
    PropertyContainer = &lt;span style="color:Blue;"&gt;new&lt;/span&gt; NamedProperty&amp;lt;&lt;span style="color:Blue;"&gt;string&lt;/span&gt;&amp;gt; 
    {
        Name = &lt;span style="color:#A31515;"&gt;&amp;quot;Name&amp;quot;&lt;/span&gt;,
        Value = c.Name,
        Next = &lt;span style="color:Blue;"&gt;new&lt;/span&gt; NamedProperty&amp;lt;IEnumerable&amp;lt;Order&amp;gt;&amp;gt;
        {
            Name = &lt;span style="color:#A31515;"&gt;&amp;quot;Orders&amp;quot;&lt;/span&gt;,
            Value = c.Orders.Select&amp;lt;Order, Wrapper&amp;gt;(o =&amp;gt; &lt;span style="color:Blue;"&gt;new&lt;/span&gt; Wrapper
            {
                TypeName = o &lt;span style="color:Blue;"&gt;is&lt;/span&gt; SpecialOrder ? typeNameSpecialOrder : typeNameOrder
                Instance = o
            }
        })
    }
});
&lt;/pre&gt;&lt;/div&gt;&lt;pre&gt;Response:
{
  &amp;quot;__type&amp;quot;: &amp;quot;NS.Customer&amp;quot;,
  &amp;quot;Name&amp;quot;: &amp;quot;Raghu&amp;quot;,
  &amp;quot;Orders&amp;quot;: [
    {
      &amp;quot;__type&amp;quot;: &amp;quot;NS.Order&amp;quot;,
      &amp;quot;ID&amp;quot;: 1,
      &amp;quot;Amount&amp;quot;: 400
    }
  ]
}
{
  &amp;quot;__type&amp;quot;: &amp;quot;NS.SpecialCustomer&amp;quot;,
  &amp;quot;Name&amp;quot;: &amp;quot;Ram&amp;quot;,
  &amp;quot;Orders&amp;quot;: [
    {
      &amp;quot;__type&amp;quot;: &amp;quot;NS.Order&amp;quot;,
      &amp;quot;ID&amp;quot;: 2,
      &amp;quot;Amount&amp;quot;: 1000
    }
  ]
}&lt;/pre&gt;&lt;h6&gt;selecting properties from expanded results&lt;/h6&gt;&lt;div style="color:Black;background-color:White;"&gt;&lt;pre&gt;
uri = &lt;span style="color:#A31515;"&gt;&amp;quot;~/Customers?$select=Name,Orders/ID,Orders/Amount&amp;amp;$expand=Orders&amp;quot;&lt;/span&gt;;
query = customers.Select(c =&amp;gt; &lt;span style="color:Blue;"&gt;new&lt;/span&gt; SelectExpandWrapper&amp;lt;Customer&amp;gt;
{
    TypeName = c &lt;span style="color:Blue;"&gt;is&lt;/span&gt; SpecialCustomer ? typeNameSpecialCustomer : typeNameCustomer,
    PropertyContainer = &lt;span style="color:Blue;"&gt;new&lt;/span&gt; NamedProperty&amp;lt;&lt;span style="color:Blue;"&gt;string&lt;/span&gt;&amp;gt;
    {
        Name = &lt;span style="color:#A31515;"&gt;&amp;quot;Name&amp;quot;&lt;/span&gt;,
        Value = c.Name,
        Next = &lt;span style="color:Blue;"&gt;new&lt;/span&gt; NamedProperty&amp;lt;IEnumerable&amp;lt;SelectExpandWrapper&amp;lt;Order&amp;gt;&amp;gt;&amp;gt;
        {
            Name = &lt;span style="color:#A31515;"&gt;&amp;quot;Orders&amp;quot;&lt;/span&gt;,
            Value = c.Orders(o =&amp;gt; &lt;span style="color:Blue;"&gt;new&lt;/span&gt; SelectExpandWrapper&amp;lt;Order&amp;gt;
            {
                TypeName = o &lt;span style="color:Blue;"&gt;is&lt;/span&gt; SpecialOrder ? typeNameSpecialOrder : typeNameOrder,
                PropertyContainer = &lt;span style="color:Blue;"&gt;new&lt;/span&gt; NamedProperty&amp;lt;&lt;span style="color:Blue;"&gt;int&lt;/span&gt;&amp;gt;
                {
                    Name = &lt;span style="color:#A31515;"&gt;&amp;quot;ID&amp;quot;&lt;/span&gt;,
                    Value = o.ID,
                    Next = &lt;span style="color:Blue;"&gt;new&lt;/span&gt; NamedProperty&amp;lt;&lt;span style="color:Blue;"&gt;int&lt;/span&gt;&amp;gt; 
                    {
                        Name = &lt;span style="color:#A31515;"&gt;&amp;quot;Amount&amp;quot;&lt;/span&gt;,
                        Value = o.Amount
                    }
                }
            }
    })
});
&lt;/pre&gt;&lt;/div&gt;Response:&lt;br /&gt;&lt;pre&gt;{
  &amp;quot;__type&amp;quot;: &amp;quot;NS.Customer&amp;quot;,
  &amp;quot;Name&amp;quot;: &amp;quot;Raghu&amp;quot;,
  &amp;quot;Orders&amp;quot;: [
    {
      &amp;quot;__type&amp;quot;: &amp;quot;NS.Order&amp;quot;,
      &amp;quot;ID&amp;quot;: 1,
      &amp;quot;Amount&amp;quot;: 400
    }
  ]
}
{
  &amp;quot;__type&amp;quot;: &amp;quot;NS.SpecialCustomer&amp;quot;,
  &amp;quot;Name&amp;quot;: &amp;quot;Ram&amp;quot;,
  &amp;quot;Orders&amp;quot;: [
    {
      &amp;quot;__type&amp;quot;: &amp;quot;NS.Order&amp;quot;,
      &amp;quot;ID&amp;quot;: 2,
      &amp;quot;Amount&amp;quot;: 1000
    }
  ]
}&lt;/pre&gt;
&lt;h6&gt;expanding properties on derived types&lt;/h6&gt;&lt;div style="color:Black;background-color:White;"&gt;&lt;pre&gt;
uri = &lt;span style="color:#A31515;"&gt;&amp;quot;~/Customers?$expand=NS.SpecialCustomer/SpecialOrders&amp;quot;&lt;/span&gt;;
query = customers.Select(c =&amp;gt; &lt;span style="color:Blue;"&gt;new&lt;/span&gt; SelectExpandWrapper&amp;lt;Customer&amp;gt;
{
    TypeName = c &lt;span style="color:Blue;"&gt;is&lt;/span&gt; SpecialCustomer ? typeNameSpecialCustomer : typeNameCustomer,
    Instance = c,
    PropertyContainer = &lt;span style="color:Blue;"&gt;new&lt;/span&gt; NamedProperty&amp;lt;SpecialCustomer&amp;gt;
    {
        Name = c &lt;span style="color:Blue;"&gt;is&lt;/span&gt; SpecialCustomer ? &lt;span style="color:#A31515;"&gt;&amp;quot;SpecialOrders&amp;quot;&lt;/span&gt; : &lt;span style="color:Blue;"&gt;null&lt;/span&gt;,
        Value = (c &lt;span style="color:Blue;"&gt;as&lt;/span&gt; SpecialCustomer).Orders.Select(o =&amp;gt; &lt;span style="color:Blue;"&gt;new&lt;/span&gt; SelectExpandWrapper&amp;lt;Order&amp;gt;
        {
            TypeName = o &lt;span style="color:Blue;"&gt;is&lt;/span&gt; SpecialOrder ? typeNameSpecialOrder : typeNameOrder,
            Instance = o
        }) &lt;span style="color:Green;"&gt;//requires null propagation. also don&amp;#39;t confuse null and non-existence&lt;/span&gt;
    }
});
&lt;/pre&gt;&lt;/div&gt;Response:&lt;br /&gt;&lt;pre&gt;{
  &amp;quot;__type&amp;quot;: &amp;quot;NS.Customer&amp;quot;,
  &amp;quot;ID&amp;quot;: 1,
  &amp;quot;Name&amp;quot;: &amp;quot;Raghu&amp;quot;
}
{
  &amp;quot;__type&amp;quot;: &amp;quot;NS.SpecialCustomer&amp;quot;,
  &amp;quot;ID&amp;quot;: 2,
  &amp;quot;Name&amp;quot;: &amp;quot;Ram&amp;quot;,
  &amp;quot;SpecialOrders&amp;quot;: [
    {
      &amp;quot;__type&amp;quot;: &amp;quot;NS.Order&amp;quot;,
      &amp;quot;ID&amp;quot;: 2,
      &amp;quot;Amount&amp;quot;: 1000
    }
  ]
}&lt;/pre&gt;
&lt;h6&gt;selecting properties on derived types&lt;/h6&gt;&lt;div style="color:Black;background-color:White;"&gt;&lt;pre&gt;
uri = &lt;span style="color:#A31515;"&gt;&amp;quot;~/Customers?$select=Name,NS.SpecialCustomer/SpecialCustomerProperty&amp;quot;&lt;/span&gt;;
query = customers.Select(c =&amp;gt; &lt;span style="color:Blue;"&gt;new&lt;/span&gt; SelectExpandWrapper&amp;lt;Customer&amp;gt;
{
    TypeName = c &lt;span style="color:Blue;"&gt;is&lt;/span&gt; SpecialCustomer ? typeNameSpecialCustomer : typeNameCustomer,
    PropertyContainer = &lt;span style="color:Blue;"&gt;new&lt;/span&gt; NamedProperty&amp;lt;&lt;span style="color:Blue;"&gt;string&lt;/span&gt;&amp;gt;
    {
        Name = &lt;span style="color:#A31515;"&gt;&amp;quot;Name&amp;quot;&lt;/span&gt;,
        Value = c.Name,
        Next = &lt;span style="color:Blue;"&gt;new&lt;/span&gt; PropertyContainer&amp;lt;SpecialCustomer&amp;gt;
        {
            Name = c &lt;span style="color:Blue;"&gt;is&lt;/span&gt; SpecialCustomer ? &lt;span style="color:#A31515;"&gt;&amp;quot;SpecialCustomerProperty&amp;quot;&lt;/span&gt; : &lt;span style="color:Blue;"&gt;null&lt;/span&gt;,
            Value = (c &lt;span style="color:Blue;"&gt;as&lt;/span&gt; SpecialCustomer).SpecialCustomerProperty &lt;span style="color:Green;"&gt;// requires null propagation.&lt;/span&gt;
        }
    }
});
&lt;/pre&gt;&lt;/div&gt;Response:&lt;br /&gt;&lt;pre&gt;{
  &amp;quot;__type&amp;quot;: &amp;quot;NS.Customer&amp;quot;,
  &amp;quot;Name&amp;quot;: &amp;quot;Raghu&amp;quot;
}
{
  &amp;quot;__type&amp;quot;: &amp;quot;NS.SpecialCustomer&amp;quot;,
  &amp;quot;Name&amp;quot;: &amp;quot;Ram&amp;quot;,
  &amp;quot;SpecialCustomerProperty&amp;quot;: 42
}&lt;/pre&gt;
&lt;h6&gt;expanding properties on expanded derived types&lt;/h6&gt;&lt;div style="color:Black;background-color:White;"&gt;&lt;pre&gt;
uri = &lt;span style="color:#A31515;"&gt;&amp;quot;~/Customers?$select=Name&amp;amp;$expand=Orders,Orders/NS.SpecialOrder/SpecialCustomer&amp;quot;&lt;/span&gt;;
query = customers.Select&amp;lt;Customer, Wrapper&amp;gt;(c =&amp;gt; &lt;span style="color:Blue;"&gt;new&lt;/span&gt; SelectExpandWrapper&amp;lt;Customer&amp;gt;
{
    TypeName = c &lt;span style="color:Blue;"&gt;is&lt;/span&gt; SpecialCustomer ? typeNameSpecialCustomer : typeNameCustomer,
    PropertyContainer = &lt;span style="color:Blue;"&gt;new&lt;/span&gt; NamedProperty&amp;lt;&lt;span style="color:Blue;"&gt;string&lt;/span&gt;&amp;gt;
    {
        Name = &lt;span style="color:#A31515;"&gt;&amp;quot;Name&amp;quot;&lt;/span&gt;,
        Value = c.Name,
        Next = &lt;span style="color:Blue;"&gt;new&lt;/span&gt; NamedProperty&amp;lt;IEnumerable&amp;lt;SelectExpandWrapper&amp;lt;Order&amp;gt;&amp;gt;&amp;gt;
        {
            Name = &lt;span style="color:#A31515;"&gt;&amp;quot;Orders&amp;quot;&lt;/span&gt;,
            Value = c.Orders.Select(o =&amp;gt; &lt;span style="color:Blue;"&gt;new&lt;/span&gt; SelectExpandWrapper&amp;lt;Order&amp;gt;
            {
                Instance = o,
                Name = o &lt;span style="color:Blue;"&gt;is&lt;/span&gt; SpecialOrder ? &lt;span style="color:#A31515;"&gt;&amp;quot;SpecialCustomer&amp;quot;&lt;/span&gt; : &lt;span style="color:Blue;"&gt;null&lt;/span&gt;, &lt;span style="color:Green;"&gt;// optional property&lt;/span&gt;
                Value = &lt;span style="color:Blue;"&gt;new&lt;/span&gt; Wrapper
                {
                    Instance = (o &lt;span style="color:Blue;"&gt;as&lt;/span&gt; SpecialOrder).SpecialCustomer
                }
            }
        }
    })
});
&lt;/pre&gt;&lt;/div&gt;Response:&lt;br /&gt;&lt;pre&gt;{
  &amp;quot;__type&amp;quot;: &amp;quot;NS.Customer&amp;quot;,
  &amp;quot;Name&amp;quot;: &amp;quot;Raghu&amp;quot;,
  &amp;quot;Orders&amp;quot;: [
    {
      &amp;quot;__type&amp;quot;: null,
      &amp;quot;ID&amp;quot;: 1,
      &amp;quot;Amount&amp;quot;: 400
    }
  ]
}
{
  &amp;quot;__type&amp;quot;: &amp;quot;NS.SpecialCustomer&amp;quot;,
  &amp;quot;Name&amp;quot;: &amp;quot;Ram&amp;quot;,
  &amp;quot;Orders&amp;quot;: [
    {
      &amp;quot;__type&amp;quot;: null,
      &amp;quot;ID&amp;quot;: 2,
      &amp;quot;Amount&amp;quot;: 1000,
      &amp;quot;SpecialCustomer&amp;quot;: {
        &amp;quot;__type&amp;quot;: &amp;quot;NS.SpecialCustomer&amp;quot;,
        &amp;quot;ID&amp;quot;: 2,
        &amp;quot;Name&amp;quot;: &amp;quot;Ram&amp;quot;,
        &amp;quot;SpecialCustomerProperty&amp;quot;: 42
      }
    }
  ]
}&lt;/pre&gt;&lt;/div&gt;&lt;div class="ClearBoth"&gt;&lt;/div&gt;</description><author>raghuramn</author><pubDate>Thu, 09 May 2013 20:46:52 GMT</pubDate><guid isPermaLink="false">Updated Wiki: $select and $expand support 20130509084652P</guid></item><item><title>Updated Wiki: $select and $expand support</title><link>https://aspnetwebstack.codeplex.com/wikipage?title=$select and $expand support&amp;version=25</link><description>&lt;div class="wikidoc"&gt;&lt;h1&gt;$select and $expand support&lt;/h1&gt;&lt;hr /&gt;
The $select system query option allows clients to requests a limited set of information for each entity or complex type identified by the ResourcePath and other System Query Options like $filter, $top, $skip etc. The $select query option is often used in conjunction with the $expand query option, to first increase the scope of the resource graph returned ($expand) and then selectively prune that resource graph ($select).&lt;br /&gt;&lt;br /&gt;The $expand system query option allows clients to request related resources when a resource that satisfies a particular request is retrieved.&lt;br /&gt;&lt;br /&gt;The following model would be used for the rest of the scenarios,&lt;br /&gt;&lt;br /&gt;&lt;div style="color:Black;background-color:White;"&gt;&lt;pre&gt;
&lt;span style="color:Blue;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;"&gt;class&lt;/span&gt; Customer
{
    &lt;span style="color:Blue;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;"&gt;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&lt;/span&gt; &lt;span style="color:Blue;"&gt;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:Blue;"&gt;virtual&lt;/span&gt; ICollection&amp;lt;Order&amp;gt; Orders { &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:Blue;"&gt;class&lt;/span&gt; SpecialCustomer : Customer
{
    &lt;span style="color:Blue;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;"&gt;int&lt;/span&gt; SpecialCustomerProperty { &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:Blue;"&gt;virtual&lt;/span&gt; ICollection&amp;lt;SpecialOrder&amp;gt; SpecialOrders { &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:Blue;"&gt;class&lt;/span&gt; Order
{
    &lt;span style="color:Blue;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;"&gt;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&lt;/span&gt; &lt;span style="color:Blue;"&gt;int&lt;/span&gt; Amount { &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; Customer Customer { &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:Blue;"&gt;class&lt;/span&gt; SpecialOrder : Order
{
    &lt;span style="color:Blue;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;"&gt;int&lt;/span&gt; SpecialOrderProperty { &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:Blue;"&gt;virtual&lt;/span&gt; SpecialCustomer SpecialCustomer { &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;private&lt;/span&gt; &lt;span style="color:Blue;"&gt;static&lt;/span&gt; IEdmModel GetModel()
{
    ODataConventionModelBuilder builder = &lt;span style="color:Blue;"&gt;new&lt;/span&gt; ODataConventionModelBuilder();
    builder.EntitySet&amp;lt;Customer&amp;gt;(&lt;span style="color:#A31515;"&gt;&amp;quot;Customers&amp;quot;&lt;/span&gt;);
    builder.EntitySet&amp;lt;Order&amp;gt;(&lt;span style="color:#A31515;"&gt;&amp;quot;Orders&amp;quot;&lt;/span&gt;);
    &lt;span style="color:Blue;"&gt;return&lt;/span&gt; builder.GetEdmModel();
}
&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;For example, assuming that a service exposes two entity sets ‘Customers’ and ‘Orders’ and a customer has 1..* (one-to-many) relationship with order, the following URL’s are valid,&lt;br /&gt;
&lt;h3&gt;Supported scenarios&lt;/h3&gt;&lt;a href="http://server/Customers?$select=Id,Name"&gt;http://server/Customers?$select=Id,Name&lt;/a&gt; &lt;br /&gt;Response should contain only the properties Id and Name for each customer. Navigation link for the property Orders must not be present in the response.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://server/Customers?$expand=Orders"&gt;http://server/Customers?$expand=Orders&lt;/a&gt; &lt;br /&gt;Response should contain all the properties of Customer for each customer. It should also contain the expanded Orders for each customer along with the navigation link (depending on the metadata level though). The expanded Orders should contain all structural properties of Orders and navigation link for each navigation property on Order.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://server/Customers?$select=Id,Name,Orders&amp;amp;$expand=Orders"&gt;http://server/Customers?$select=Id,Name,Orders&amp;amp;$expand=Orders&lt;/a&gt; &lt;br /&gt;Response should contain properties Id and Name for each customer and expanded Orders. Each expanded Order should contain all the structural properties of order and a navigation link for each navigation property of order.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://server/Customers?$select=Orders/Id&amp;amp;$expand=Orders"&gt;http://server/Customers?$select=Orders/Id&amp;amp;$expand=Orders&lt;/a&gt; &lt;br /&gt;Selection on an expanded property.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://server/Customers?$select=Id,NS.SpecialCustomer/SpecialId"&gt;http://server/Customers?$select=Id,NS.SpecialCustomer/SpecialId&lt;/a&gt; &lt;br /&gt;Response should contain Id property for each customer and also includes the SpecialId property for each special customer. ODataLib uri parser doesn’t support this yet.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://server/Customers?$expand=NS.SpecialCustomer/SpecialOrder"&gt;http://server/Customers?$expand=NS.SpecialCustomer/SpecialOrder&lt;/a&gt; &lt;br /&gt;Response should contain all structural properties and expand the SpecialOrder property for each special customer. A normal customer would have his navigation links as deferred content in the response. ODataLib uri parser doesn’t support this yet.&lt;br /&gt;&lt;br /&gt;
&lt;h3&gt;Not supported scenarios&lt;/h3&gt;&lt;a href="http://server/Customers(42)/Address?$select=City"&gt;http://server/Customers(42)/Address?$select=City&lt;/a&gt;&lt;br /&gt;Selections of complex types is not supported. (OData V4 might have support for it though)&lt;br /&gt;
&lt;h3&gt;Considerations and Open questions&lt;/h3&gt;There are several open questions that have to be discussed and concluded.
&lt;h4&gt;Support for other formatters&lt;/h4&gt;&lt;ol&gt;&lt;li&gt;Should we support $select with json and xml formatters? $expand is not important as these formatters expand by default. &lt;/li&gt;
&lt;li&gt;Should we change the behavior of these formatters to not expand by default if the incoming query contains a $expand clause?&lt;/li&gt;&lt;/ol&gt;
&lt;h4&gt;Query optimizations&lt;/h4&gt;1. Should $select be optimized? 
&lt;ul&gt;&lt;li&gt;$select is a shape changing query. From a web API perspective, this would mean that the ObjectContent&amp;lt;T&amp;gt; has to be reconstructed. What would happen to the content headers on the ObjectContent? Should we just do a content-negotiation again and say that any content-type headers set after the action finished and before the QueryableAttribute runs would be lost?&lt;/li&gt;
&lt;li&gt;An un-optimized $select would mean more memory allocation on the database.&lt;/li&gt;&lt;/ul&gt;
&lt;blockquote&gt;&lt;blockquote&gt;&lt;i&gt; design meeting@Mar 28&lt;sup&gt;th&lt;/sup&gt;: First cut, actions returning IQueryable will support $select and $expand as it won&amp;#39;t be a shape changing query anymore. $select will be optimized. &lt;/i&gt;&lt;/blockquote&gt;&lt;/blockquote&gt;
2. $expand has to be optimized.
&lt;ul&gt;&lt;li&gt;Without an optimized $expand no-one would ever use our $expand support unless they are building on top of in-memory IQueryable.&lt;/li&gt;
&lt;li&gt;How would the generated query look like? Should we just support EF or try be compatible with some other providers? (Scoping question).&lt;/li&gt;
&lt;li&gt;If we do it only for EF, what is the extensibility story for custom providers?&lt;/li&gt;&lt;/ul&gt;
&lt;blockquote&gt;&lt;blockquote&gt;&lt;i&gt; design meeting@Mar 28&lt;sup&gt;th&lt;/sup&gt;: work item: update with the queries &lt;/i&gt;&lt;/blockquote&gt;&lt;/blockquote&gt;
3. $select and $expand can be done on a single entity. In these cases there is no IQueryable returned by the action. How can we do query manipulation in this scenario? For example, http://server/Customers(42)?$select=Name maps to an web API action &lt;br /&gt;&lt;span class="codeInline"&gt; public Customer GetCustomer(int key). &lt;/span&gt;&lt;br /&gt;
&lt;h4&gt;PageSize for expanded feeds. &lt;/h4&gt;&lt;ol&gt;&lt;li&gt;How can one specify page size for expanded feeds? WCF DS has a per entity-set configuration knob for page size. Should we follow their model? &lt;/li&gt;&lt;/ol&gt;

&lt;h2&gt;Implementation details&lt;/h2&gt;The idea here is that a selection ($select) results in a LINQ .Select query using a wrapper class (kind of an static anonymous type) as the response. The wrapper class contains the properties that have to be included in the selection. For example, a $select involving a selection having one property uses a wrapper class that looks like this,&lt;br /&gt;&lt;div style="color:Black;background-color:White;"&gt;&lt;pre&gt;
&lt;span style="color:Blue;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;"&gt;class&lt;/span&gt; SelectExpandWrapper&amp;lt;TElement&amp;gt; 
{
    &lt;span style="color:Blue;"&gt;public&lt;/span&gt; PropertyContainer Container { &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;internal&lt;/span&gt; &lt;span style="color:Blue;"&gt;abstract&lt;/span&gt; &lt;span style="color:Blue;"&gt;class&lt;/span&gt; PropertyContainer
{
        &lt;span style="color:Blue;"&gt;public&lt;/span&gt; Dictionary&amp;lt;&lt;span style="color:Blue;"&gt;string&lt;/span&gt;, &lt;span style="color:Blue;"&gt;object&lt;/span&gt;&amp;gt; ToDictionary(&lt;span style="color:Blue;"&gt;bool&lt;/span&gt; includeAutoSelected = &lt;span style="color:Blue;"&gt;true&lt;/span&gt;)
}
&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;Also, we wanted to free the OData formatter from having to look at the $select and $expand options. To support that, the wrapper class should contain information about three things,
&lt;ol&gt;&lt;li&gt;what structural properties/navigation properties have to be serialized.&lt;/li&gt;
&lt;li&gt;what actions have to be included in the response.&lt;/li&gt;
&lt;li&gt;what navigation properties have to be expanded.&lt;/li&gt;&lt;/ol&gt;
&lt;br /&gt;To support that the wrapper should also implement the IEdmStructuredObject interface.&lt;br /&gt;&lt;pre&gt;public interface IEdmStructuredObject : IEdmObject
{
        bool TryGetValue(string propertyName, out object value);
}

public interface IEdmObject
{
        IEdmTypeReference GetEdmType();
}&lt;/pre&gt;&lt;br /&gt;The IEdmObject interface is just a way to get the EDM type name required for odata serialization and also provides a dynamic property accessor to separate the implementation of the Wrapper from the formatter. Users who don&amp;#39;t like our Wrapper implementation (geared towards EF and Linq2Objects) could consider doing their own implementations.&lt;br /&gt;
&lt;h4&gt;Generated queries&lt;/h4&gt;There are two things to consider here. &lt;br /&gt;
&lt;ol&gt;&lt;li&gt;OData formatter (in the default case), requires the key properties to generate navigation links. So, even if the client did not ask for key properties explicitly in the request, they have to be fetched from the database. We should probably have an extension point here, so that people who customize link generation can fetch extra properties if they want them for link generation.&lt;/li&gt;
&lt;li&gt;OData formatter requires the type name of the entity while writing responses. If we are getting a partial object from the database (wrapper class), we have to include the type name in the wrapper class. &lt;/li&gt;&lt;/ol&gt;
&lt;br /&gt;&lt;br /&gt;I am listing out the possible generated LINQ queries here for some scenarios for reference. The generated SQL queries (using EF) would be too complex in some cases. If you really want to look at them, refer to the following dump files,
&lt;ol&gt;&lt;li&gt;using Table per hierarchy strategy (TPH) which is code first default - &lt;a href="https://www.codeplex.com/Download?ProjectName=ASPNETWebStack&amp;DownloadId=647202"&gt;tph_dump.txt&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;using table per type strategy (TPT) - &lt;a href="https://www.codeplex.com/Download?ProjectName=ASPNETWebStack&amp;DownloadId=647201"&gt;tpt_dump.txt&lt;/a&gt;&lt;/li&gt;&lt;/ol&gt;
Also, if you are interested in playing around with the sample, I have the cs file &lt;a href="https://www.codeplex.com/Download?ProjectName=ASPNETWebStack&amp;DownloadId=647200"&gt;here&lt;/a&gt;.&lt;br /&gt;
&lt;h6&gt;simple $select&lt;/h6&gt;&lt;div style="color:Black;background-color:White;"&gt;&lt;pre&gt;
uri = &lt;span style="color:#A31515;"&gt;&amp;quot;~/Customers?$select=ID&amp;quot;&lt;/span&gt;;
query = customers.Select&amp;lt;Customer, Wrapper&amp;gt;(c =&amp;gt; &lt;span style="color:Blue;"&gt;new&lt;/span&gt; Wrapper&amp;lt;&lt;span style="color:Blue;"&gt;int&lt;/span&gt;&amp;gt;
{
    TypeName = c &lt;span style="color:Blue;"&gt;is&lt;/span&gt; SpecialCustomer ? typeNameSpecialCustomer : typeNameCustomer,
    Name1 = &lt;span style="color:#A31515;"&gt;&amp;quot;ID&amp;quot;&lt;/span&gt;,
    Value1 = c.ID
});
&lt;/pre&gt;&lt;/div&gt;Response:&lt;br /&gt;&lt;pre&gt;{
  &amp;quot;__type&amp;quot;: &amp;quot;NS.Customer&amp;quot;,
  &amp;quot;ID&amp;quot;: 1
}
{
  &amp;quot;__type&amp;quot;: &amp;quot;NS.SpecialCustomer&amp;quot;,
  &amp;quot;ID&amp;quot;: 2
}&lt;/pre&gt;
&lt;h6&gt;simple $expand&lt;/h6&gt;&lt;div style="color:Black;background-color:White;"&gt;&lt;pre&gt;
uri = &lt;span style="color:#A31515;"&gt;&amp;quot;~/Customers?$expand=Orders&amp;quot;&lt;/span&gt;;
query = customers.Select(c =&amp;gt; &lt;span style="color:Blue;"&gt;new&lt;/span&gt; SelectExpandWrapper&amp;lt;Customer&amp;gt;
{
    TypeName = c &lt;span style="color:Blue;"&gt;is&lt;/span&gt; SpecialCustomer ? typeNameSpecialCustomer : typeNameCustomer,
    Instance = c,
    PropertyContainer = &lt;span style="color:Blue;"&gt;new&lt;/span&gt; NamedProperty&amp;lt;Order&amp;gt;
    {
        Name = &lt;span style="color:#A31515;"&gt;&amp;quot;Orders&amp;quot;&lt;/span&gt;,
        Value = c.Orders.Select(o =&amp;gt; &lt;span style="color:Blue;"&gt;new&lt;/span&gt; SelectExpandWrapper
        {
            TypeName = o &lt;span style="color:Blue;"&gt;is&lt;/span&gt; SpecialOrder ? typeNameSpecialOrder : typeNameOrder,
            Instance = o
        })
    }
});
&lt;/pre&gt;&lt;/div&gt;Response:&lt;br /&gt;&lt;pre&gt;{
  &amp;quot;__type&amp;quot;: &amp;quot;NS.Customer&amp;quot;,
  &amp;quot;ID&amp;quot;: 1,
  &amp;quot;Name&amp;quot;: &amp;quot;Raghu&amp;quot;,
  &amp;quot;Orders&amp;quot;: [
    {
      &amp;quot;__type&amp;quot;: &amp;quot;NS.Order&amp;quot;,
      &amp;quot;ID&amp;quot;: 1,
      &amp;quot;Amount&amp;quot;: 400
    }
  ]
}
{
  &amp;quot;__type&amp;quot;: &amp;quot;NS.SpecialCustomer&amp;quot;,
  &amp;quot;ID&amp;quot;: 2,
  &amp;quot;Name&amp;quot;: &amp;quot;Ram&amp;quot;,
  &amp;quot;Orders&amp;quot;: [
    {
      &amp;quot;__type&amp;quot;: &amp;quot;NS.Order&amp;quot;,
      &amp;quot;ID&amp;quot;: 2,
      &amp;quot;Amount&amp;quot;: 1000
    }
  ]
}&lt;/pre&gt;
&lt;h6&gt;simple $select and $expand&lt;/h6&gt;&lt;div style="color:Black;background-color:White;"&gt;&lt;pre&gt;
uri = &lt;span style="color:#A31515;"&gt;&amp;quot;~/Customers?$select=Name,Orders&amp;amp;$expand=Orders&amp;quot;&lt;/span&gt;;
query = customers.Select(c =&amp;gt; &lt;span style="color:Blue;"&gt;new&lt;/span&gt; SelectExpandWrapper&amp;lt;Customer&amp;gt;
{
    TypeName = c &lt;span style="color:Blue;"&gt;is&lt;/span&gt; SpecialCustomer ? typeNameSpecialCustomer : typeNameCustomer,
    PropertyContainer = &lt;span style="color:Blue;"&gt;new&lt;/span&gt; NamedProperty&amp;lt;&lt;span style="color:Blue;"&gt;string&lt;/span&gt;&amp;gt; 
    {
        Name = &lt;span style="color:#A31515;"&gt;&amp;quot;Name&amp;quot;&lt;/span&gt;,
        Value = c.Name,
        Next = &lt;span style="color:Blue;"&gt;new&lt;/span&gt; NamedProperty&amp;lt;IEnumerable&amp;lt;Order&amp;gt;&amp;gt;
        {
            Name = &lt;span style="color:#A31515;"&gt;&amp;quot;Orders&amp;quot;&lt;/span&gt;,
            Value = c.Orders.Select&amp;lt;Order, Wrapper&amp;gt;(o =&amp;gt; &lt;span style="color:Blue;"&gt;new&lt;/span&gt; Wrapper
            {
                TypeName = o &lt;span style="color:Blue;"&gt;is&lt;/span&gt; SpecialOrder ? typeNameSpecialOrder : typeNameOrder
                Instance = o
            }
        })
    }
});
&lt;/pre&gt;&lt;/div&gt;&lt;pre&gt;Response:
{
  &amp;quot;__type&amp;quot;: &amp;quot;NS.Customer&amp;quot;,
  &amp;quot;Name&amp;quot;: &amp;quot;Raghu&amp;quot;,
  &amp;quot;Orders&amp;quot;: [
    {
      &amp;quot;__type&amp;quot;: &amp;quot;NS.Order&amp;quot;,
      &amp;quot;ID&amp;quot;: 1,
      &amp;quot;Amount&amp;quot;: 400
    }
  ]
}
{
  &amp;quot;__type&amp;quot;: &amp;quot;NS.SpecialCustomer&amp;quot;,
  &amp;quot;Name&amp;quot;: &amp;quot;Ram&amp;quot;,
  &amp;quot;Orders&amp;quot;: [
    {
      &amp;quot;__type&amp;quot;: &amp;quot;NS.Order&amp;quot;,
      &amp;quot;ID&amp;quot;: 2,
      &amp;quot;Amount&amp;quot;: 1000
    }
  ]
}&lt;/pre&gt;&lt;h6&gt;selecting properties from expanded results&lt;/h6&gt;&lt;div style="color:Black;background-color:White;"&gt;&lt;pre&gt;
uri = &lt;span style="color:#A31515;"&gt;&amp;quot;~/Customers?$select=Name,Orders/ID,Orders/Amount&amp;amp;$expand=Orders&amp;quot;&lt;/span&gt;;
query = customers.Select(c =&amp;gt; &lt;span style="color:Blue;"&gt;new&lt;/span&gt; SelectExpandWrapper&amp;lt;Customer&amp;gt;
{
    TypeName = c &lt;span style="color:Blue;"&gt;is&lt;/span&gt; SpecialCustomer ? typeNameSpecialCustomer : typeNameCustomer,
    PropertyContainer = &lt;span style="color:Blue;"&gt;new&lt;/span&gt; NamedProperty&amp;lt;&lt;span style="color:Blue;"&gt;string&lt;/span&gt;&amp;gt;
    {
        Name = &lt;span style="color:#A31515;"&gt;&amp;quot;Name&amp;quot;&lt;/span&gt;,
        Value = c.Name,
        Next = &lt;span style="color:Blue;"&gt;new&lt;/span&gt; NamedProperty&amp;lt;IEnumerable&amp;lt;SelectExpandWrapper&amp;lt;Order&amp;gt;&amp;gt;&amp;gt;
        {
            Name = &lt;span style="color:#A31515;"&gt;&amp;quot;Orders&amp;quot;&lt;/span&gt;,
            Value = c.Orders(o =&amp;gt; &lt;span style="color:Blue;"&gt;new&lt;/span&gt; SelectExpandWrapper&amp;lt;Order&amp;gt;
            {
                TypeName = o &lt;span style="color:Blue;"&gt;is&lt;/span&gt; SpecialOrder ? typeNameSpecialOrder : typeNameOrder,
                PropertyContainer = &lt;span style="color:Blue;"&gt;new&lt;/span&gt; NamedProperty&amp;lt;&lt;span style="color:Blue;"&gt;int&lt;/span&gt;&amp;gt;
                {
                    Name = &lt;span style="color:#A31515;"&gt;&amp;quot;ID&amp;quot;&lt;/span&gt;,
                    Value = o.ID,
                    Next = &lt;span style="color:Blue;"&gt;new&lt;/span&gt; NamedProperty&amp;lt;&lt;span style="color:Blue;"&gt;int&lt;/span&gt;&amp;gt; 
                    {
                        Name = &lt;span style="color:#A31515;"&gt;&amp;quot;Amount&amp;quot;&lt;/span&gt;,
                        Value = o.Amount
                    }
                }
            }
    })
});
&lt;/pre&gt;&lt;/div&gt;Response:&lt;br /&gt;&lt;pre&gt;{
  &amp;quot;__type&amp;quot;: &amp;quot;NS.Customer&amp;quot;,
  &amp;quot;Name&amp;quot;: &amp;quot;Raghu&amp;quot;,
  &amp;quot;Orders&amp;quot;: [
    {
      &amp;quot;__type&amp;quot;: &amp;quot;NS.Order&amp;quot;,
      &amp;quot;ID&amp;quot;: 1,
      &amp;quot;Amount&amp;quot;: 400
    }
  ]
}
{
  &amp;quot;__type&amp;quot;: &amp;quot;NS.SpecialCustomer&amp;quot;,
  &amp;quot;Name&amp;quot;: &amp;quot;Ram&amp;quot;,
  &amp;quot;Orders&amp;quot;: [
    {
      &amp;quot;__type&amp;quot;: &amp;quot;NS.Order&amp;quot;,
      &amp;quot;ID&amp;quot;: 2,
      &amp;quot;Amount&amp;quot;: 1000
    }
  ]
}&lt;/pre&gt;
&lt;h6&gt;expanding properties on derived types&lt;/h6&gt;&lt;div style="color:Black;background-color:White;"&gt;&lt;pre&gt;
uri = &lt;span style="color:#A31515;"&gt;&amp;quot;~/Customers?$expand=NS.SpecialCustomer/SpecialOrders&amp;quot;&lt;/span&gt;;
query = customers.Select(c =&amp;gt; &lt;span style="color:Blue;"&gt;new&lt;/span&gt; SelectExpandWrapper&amp;lt;Customer&amp;gt;
{
    TypeName = c &lt;span style="color:Blue;"&gt;is&lt;/span&gt; SpecialCustomer ? typeNameSpecialCustomer : typeNameCustomer,
    Instance = c,
    PropertyContainer = &lt;span style="color:Blue;"&gt;new&lt;/span&gt; NamedProperty&amp;lt;SpecialCustomer&amp;gt;
    {
        Name = c &lt;span style="color:Blue;"&gt;is&lt;/span&gt; SpecialCustomer ? &lt;span style="color:#A31515;"&gt;&amp;quot;SpecialOrders&amp;quot;&lt;/span&gt; : &lt;span style="color:Blue;"&gt;null&lt;/span&gt;,
        Value = (c &lt;span style="color:Blue;"&gt;as&lt;/span&gt; SpecialCustomer).Orders.Select(o =&amp;gt; &lt;span style="color:Blue;"&gt;new&lt;/span&gt; SelectExpandWrapper&amp;lt;Order&amp;gt;
        {
            TypeName = o &lt;span style="color:Blue;"&gt;is&lt;/span&gt; SpecialOrder ? typeNameSpecialOrder : typeNameOrder,
            Instance = o
        }) &lt;span style="color:Green;"&gt;//requires null propagation. also don&amp;#39;t confuse null and non-existence&lt;/span&gt;
    }
});
&lt;/pre&gt;&lt;/div&gt;Response:&lt;br /&gt;&lt;pre&gt;{
  &amp;quot;__type&amp;quot;: &amp;quot;NS.Customer&amp;quot;,
  &amp;quot;ID&amp;quot;: 1,
  &amp;quot;Name&amp;quot;: &amp;quot;Raghu&amp;quot;
}
{
  &amp;quot;__type&amp;quot;: &amp;quot;NS.SpecialCustomer&amp;quot;,
  &amp;quot;ID&amp;quot;: 2,
  &amp;quot;Name&amp;quot;: &amp;quot;Ram&amp;quot;,
  &amp;quot;SpecialOrders&amp;quot;: [
    {
      &amp;quot;__type&amp;quot;: &amp;quot;NS.Order&amp;quot;,
      &amp;quot;ID&amp;quot;: 2,
      &amp;quot;Amount&amp;quot;: 1000
    }
  ]
}&lt;/pre&gt;
&lt;h6&gt;selecting properties on derived types&lt;/h6&gt;&lt;div style="color:Black;background-color:White;"&gt;&lt;pre&gt;
uri = &lt;span style="color:#A31515;"&gt;&amp;quot;~/Customers?$select=Name,NS.SpecialCustomer/SpecialCustomerProperty&amp;quot;&lt;/span&gt;;
query = customers.Select(c =&amp;gt; &lt;span style="color:Blue;"&gt;new&lt;/span&gt; SelectExpandWrapper&amp;lt;Customer&amp;gt;
{
    TypeName = c &lt;span style="color:Blue;"&gt;is&lt;/span&gt; SpecialCustomer ? typeNameSpecialCustomer : typeNameCustomer,
    PropertyContainer = &lt;span style="color:Blue;"&gt;new&lt;/span&gt; NamedProperty&amp;lt;&lt;span style="color:Blue;"&gt;string&lt;/span&gt;&amp;gt;
    {
        Name = &lt;span style="color:#A31515;"&gt;&amp;quot;Name&amp;quot;&lt;/span&gt;,
        Value = c.Name,
        Next = &lt;span style="color:Blue;"&gt;new&lt;/span&gt; PropertyContainer&amp;lt;SpecialCustomer&amp;gt;
        {
            Name = c &lt;span style="color:Blue;"&gt;is&lt;/span&gt; SpecialCustomer ? &lt;span style="color:#A31515;"&gt;&amp;quot;SpecialCustomerProperty&amp;quot;&lt;/span&gt; : &lt;span style="color:Blue;"&gt;null&lt;/span&gt;,
            Value = (c &lt;span style="color:Blue;"&gt;as&lt;/span&gt; SpecialCustomer).SpecialCustomerProperty &lt;span style="color:Green;"&gt;// requires null propagation.&lt;/span&gt;
        }
    }
});
&lt;/pre&gt;&lt;/div&gt;Response:&lt;br /&gt;&lt;pre&gt;{
  &amp;quot;__type&amp;quot;: &amp;quot;NS.Customer&amp;quot;,
  &amp;quot;Name&amp;quot;: &amp;quot;Raghu&amp;quot;
}
{
  &amp;quot;__type&amp;quot;: &amp;quot;NS.SpecialCustomer&amp;quot;,
  &amp;quot;Name&amp;quot;: &amp;quot;Ram&amp;quot;,
  &amp;quot;SpecialCustomerProperty&amp;quot;: 42
}&lt;/pre&gt;
&lt;h6&gt;expanding properties on expanded derived types&lt;/h6&gt;&lt;div style="color:Black;background-color:White;"&gt;&lt;pre&gt;
uri = &lt;span style="color:#A31515;"&gt;&amp;quot;~/Customers?$select=Name&amp;amp;$expand=Orders,Orders/NS.SpecialOrder/SpecialCustomer&amp;quot;&lt;/span&gt;;
query = customers.Select&amp;lt;Customer, Wrapper&amp;gt;(c =&amp;gt; &lt;span style="color:Blue;"&gt;new&lt;/span&gt; SelectExpandWrapper&amp;lt;Customer&amp;gt;
{
    TypeName = c &lt;span style="color:Blue;"&gt;is&lt;/span&gt; SpecialCustomer ? typeNameSpecialCustomer : typeNameCustomer,
    PropertyContainer = &lt;span style="color:Blue;"&gt;new&lt;/span&gt; NamedProperty&amp;lt;&lt;span style="color:Blue;"&gt;string&lt;/span&gt;&amp;gt;
    {
        Name = &lt;span style="color:#A31515;"&gt;&amp;quot;Name&amp;quot;&lt;/span&gt;,
        Value = c.Name,
        Next = &lt;span style="color:Blue;"&gt;new&lt;/span&gt; NamedProperty&amp;lt;IEnumerable&amp;lt;SelectExpandWrapper&amp;lt;Order&amp;gt;&amp;gt;&amp;gt;
        {
            Name = &lt;span style="color:#A31515;"&gt;&amp;quot;Orders&amp;quot;&lt;/span&gt;,
            Value = c.Orders.Select(o =&amp;gt; &lt;span style="color:Blue;"&gt;new&lt;/span&gt; SelectExpandWrapper&amp;lt;Order&amp;gt;
            {
                Instance = o,
                Name = o &lt;span style="color:Blue;"&gt;is&lt;/span&gt; SpecialOrder ? &lt;span style="color:#A31515;"&gt;&amp;quot;SpecialCustomer&amp;quot;&lt;/span&gt; : &lt;span style="color:Blue;"&gt;null&lt;/span&gt;, &lt;span style="color:Green;"&gt;// optional property&lt;/span&gt;
                Value = &lt;span style="color:Blue;"&gt;new&lt;/span&gt; Wrapper
                {
                    Instance = (o &lt;span style="color:Blue;"&gt;as&lt;/span&gt; SpecialOrder).SpecialCustomer
                }
            }
        }
    })
});
&lt;/pre&gt;&lt;/div&gt;Response:&lt;br /&gt;&lt;pre&gt;{
  &amp;quot;__type&amp;quot;: &amp;quot;NS.Customer&amp;quot;,
  &amp;quot;Name&amp;quot;: &amp;quot;Raghu&amp;quot;,
  &amp;quot;Orders&amp;quot;: [
    {
      &amp;quot;__type&amp;quot;: null,
      &amp;quot;ID&amp;quot;: 1,
      &amp;quot;Amount&amp;quot;: 400
    }
  ]
}
{
  &amp;quot;__type&amp;quot;: &amp;quot;NS.SpecialCustomer&amp;quot;,
  &amp;quot;Name&amp;quot;: &amp;quot;Ram&amp;quot;,
  &amp;quot;Orders&amp;quot;: [
    {
      &amp;quot;__type&amp;quot;: null,
      &amp;quot;ID&amp;quot;: 2,
      &amp;quot;Amount&amp;quot;: 1000,
      &amp;quot;SpecialCustomer&amp;quot;: {
        &amp;quot;__type&amp;quot;: &amp;quot;NS.SpecialCustomer&amp;quot;,
        &amp;quot;ID&amp;quot;: 2,
        &amp;quot;Name&amp;quot;: &amp;quot;Ram&amp;quot;,
        &amp;quot;SpecialCustomerProperty&amp;quot;: 42
      }
    }
  ]
}&lt;/pre&gt;&lt;/div&gt;&lt;div class="ClearBoth"&gt;&lt;/div&gt;</description><author>raghuramn</author><pubDate>Thu, 09 May 2013 20:25:19 GMT</pubDate><guid isPermaLink="false">Updated Wiki: $select and $expand support 20130509082519P</guid></item><item><title>Updated Wiki: $select and $expand support</title><link>https://aspnetwebstack.codeplex.com/wikipage?title=$select and $expand support&amp;version=24</link><description>&lt;div class="wikidoc"&gt;&lt;h1&gt;$select and $expand support&lt;/h1&gt;&lt;hr /&gt;
The $select system query option allows clients to requests a limited set of information for each entity or complex type identified by the ResourcePath and other System Query Options like $filter, $top, $skip etc. The $select query option is often used in conjunction with the $expand query option, to first increase the scope of the resource graph returned ($expand) and then selectively prune that resource graph ($select).&lt;br /&gt;&lt;br /&gt;The $expand system query option allows clients to request related resources when a resource that satisfies a particular request is retrieved.&lt;br /&gt;&lt;br /&gt;The following model would be used for the rest of the scenarios,&lt;br /&gt;&lt;br /&gt;&lt;div style="color:Black;background-color:White;"&gt;&lt;pre&gt;
&lt;span style="color:Blue;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;"&gt;class&lt;/span&gt; Customer
{
    &lt;span style="color:Blue;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;"&gt;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&lt;/span&gt; &lt;span style="color:Blue;"&gt;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:Blue;"&gt;virtual&lt;/span&gt; ICollection&amp;lt;Order&amp;gt; Orders { &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:Blue;"&gt;class&lt;/span&gt; SpecialCustomer : Customer
{
    &lt;span style="color:Blue;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;"&gt;int&lt;/span&gt; SpecialCustomerProperty { &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:Blue;"&gt;virtual&lt;/span&gt; ICollection&amp;lt;SpecialOrder&amp;gt; SpecialOrders { &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:Blue;"&gt;class&lt;/span&gt; Order
{
    &lt;span style="color:Blue;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;"&gt;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&lt;/span&gt; &lt;span style="color:Blue;"&gt;int&lt;/span&gt; Amount { &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; Customer Customer { &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:Blue;"&gt;class&lt;/span&gt; SpecialOrder : Order
{
    &lt;span style="color:Blue;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;"&gt;int&lt;/span&gt; SpecialOrderProperty { &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:Blue;"&gt;virtual&lt;/span&gt; SpecialCustomer SpecialCustomer { &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;private&lt;/span&gt; &lt;span style="color:Blue;"&gt;static&lt;/span&gt; IEdmModel GetModel()
{
    ODataConventionModelBuilder builder = &lt;span style="color:Blue;"&gt;new&lt;/span&gt; ODataConventionModelBuilder();
    builder.EntitySet&amp;lt;Customer&amp;gt;(&lt;span style="color:#A31515;"&gt;&amp;quot;Customers&amp;quot;&lt;/span&gt;);
    builder.EntitySet&amp;lt;Order&amp;gt;(&lt;span style="color:#A31515;"&gt;&amp;quot;Orders&amp;quot;&lt;/span&gt;);
    &lt;span style="color:Blue;"&gt;return&lt;/span&gt; builder.GetEdmModel();
}
&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;For example, assuming that a service exposes two entity sets ‘Customers’ and ‘Orders’ and a customer has 1..* (one-to-many) relationship with order, the following URL’s are valid,&lt;br /&gt;
&lt;h3&gt;Supported scenarios&lt;/h3&gt;&lt;a href="http://server/Customers?$select=Id,Name"&gt;http://server/Customers?$select=Id,Name&lt;/a&gt; &lt;br /&gt;Response should contain only the properties Id and Name for each customer. Navigation link for the property Orders must not be present in the response.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://server/Customers?$expand=Orders"&gt;http://server/Customers?$expand=Orders&lt;/a&gt; &lt;br /&gt;Response should contain all the properties of Customer for each customer. It should also contain the expanded Orders for each customer along with the navigation link (depending on the metadata level though). The expanded Orders should contain all structural properties of Orders and navigation link for each navigation property on Order.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://server/Customers?$select=Id,Name,Orders&amp;amp;$expand=Orders"&gt;http://server/Customers?$select=Id,Name,Orders&amp;amp;$expand=Orders&lt;/a&gt; &lt;br /&gt;Response should contain properties Id and Name for each customer and expanded Orders. Each expanded Order should contain all the structural properties of order and a navigation link for each navigation property of order.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://server/Customers?$select=Orders/Id&amp;amp;$expand=Orders"&gt;http://server/Customers?$select=Orders/Id&amp;amp;$expand=Orders&lt;/a&gt; &lt;br /&gt;Selection on an expanded property.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://server/Customers?$select=Id,NS.SpecialCustomer/SpecialId"&gt;http://server/Customers?$select=Id,NS.SpecialCustomer/SpecialId&lt;/a&gt; &lt;br /&gt;Response should contain Id property for each customer and also includes the SpecialId property for each special customer. ODataLib uri parser doesn’t support this yet.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://server/Customers?$expand=NS.SpecialCustomer/SpecialOrder"&gt;http://server/Customers?$expand=NS.SpecialCustomer/SpecialOrder&lt;/a&gt; &lt;br /&gt;Response should contain all structural properties and expand the SpecialOrder property for each special customer. A normal customer would have his navigation links as deferred content in the response. ODataLib uri parser doesn’t support this yet.&lt;br /&gt;&lt;br /&gt;
&lt;h3&gt;Not supported scenarios&lt;/h3&gt;&lt;a href="http://server/Customers(42)/Address?$select=City"&gt;http://server/Customers(42)/Address?$select=City&lt;/a&gt;&lt;br /&gt;Selections of complex types is not supported. (OData V4 might have support for it though)&lt;br /&gt;
&lt;h3&gt;Considerations and Open questions&lt;/h3&gt;There are several open questions that have to be discussed and concluded.
&lt;h4&gt;Support for other formatters&lt;/h4&gt;&lt;ol&gt;&lt;li&gt;Should we support $select with json and xml formatters? $expand is not important as these formatters expand by default. &lt;/li&gt;
&lt;li&gt;Should we change the behavior of these formatters to not expand by default if the incoming query contains a $expand clause?&lt;/li&gt;&lt;/ol&gt;
&lt;h4&gt;Query optimizations&lt;/h4&gt;1. Should $select be optimized? 
&lt;ul&gt;&lt;li&gt;$select is a shape changing query. From a web API perspective, this would mean that the ObjectContent&amp;lt;T&amp;gt; has to be reconstructed. What would happen to the content headers on the ObjectContent? Should we just do a content-negotiation again and say that any content-type headers set after the action finished and before the QueryableAttribute runs would be lost?&lt;/li&gt;
&lt;li&gt;An un-optimized $select would mean more memory allocation on the database.&lt;/li&gt;&lt;/ul&gt;
&lt;blockquote&gt;&lt;blockquote&gt;&lt;i&gt; design meeting@Mar 28&lt;sup&gt;th&lt;/sup&gt;: First cut, actions returning IQueryable will support $select and $expand as it won&amp;#39;t be a shape changing query anymore. $select will be optimized. &lt;/i&gt;&lt;/blockquote&gt;&lt;/blockquote&gt;
2. $expand has to be optimized.
&lt;ul&gt;&lt;li&gt;Without an optimized $expand no-one would ever use our $expand support unless they are building on top of in-memory IQueryable.&lt;/li&gt;
&lt;li&gt;How would the generated query look like? Should we just support EF or try be compatible with some other providers? (Scoping question).&lt;/li&gt;
&lt;li&gt;If we do it only for EF, what is the extensibility story for custom providers?&lt;/li&gt;&lt;/ul&gt;
&lt;blockquote&gt;&lt;blockquote&gt;&lt;i&gt; design meeting@Mar 28&lt;sup&gt;th&lt;/sup&gt;: work item: update with the queries &lt;/i&gt;&lt;/blockquote&gt;&lt;/blockquote&gt;
3. $select and $expand can be done on a single entity. In these cases there is no IQueryable returned by the action. How can we do query manipulation in this scenario? For example, http://server/Customers(42)?$select=Name maps to an web API action &lt;br /&gt;&lt;span class="codeInline"&gt; public Customer GetCustomer(int key). &lt;/span&gt;&lt;br /&gt;
&lt;h4&gt;PageSize for expanded feeds. &lt;/h4&gt;&lt;ol&gt;&lt;li&gt;How can one specify page size for expanded feeds? WCF DS has a per entity-set configuration knob for page size. Should we follow their model? &lt;/li&gt;&lt;/ol&gt;

&lt;h2&gt;Implementation details&lt;/h2&gt;The idea here is that a selection ($select) results in a LINQ .Select query using a wrapper class (kind of an static anonymous type) as the response. The wrapper class contains the properties that have to be included in the selection. For example, a $select involving a selection having one property uses a wrapper class that looks like this,&lt;br /&gt;&lt;div style="color:Black;background-color:White;"&gt;&lt;pre&gt;
&lt;span style="color:Blue;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;"&gt;class&lt;/span&gt; SelectExpandWrapper&amp;lt;TElement&amp;gt; 
{
    &lt;span style="color:Blue;"&gt;public&lt;/span&gt; PropertyContainer Container { &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;internal&lt;/span&gt; &lt;span style="color:Blue;"&gt;abstract&lt;/span&gt; &lt;span style="color:Blue;"&gt;class&lt;/span&gt; PropertyContainer
{
        &lt;span style="color:Blue;"&gt;public&lt;/span&gt; Dictionary&amp;lt;&lt;span style="color:Blue;"&gt;string&lt;/span&gt;, &lt;span style="color:Blue;"&gt;object&lt;/span&gt;&amp;gt; ToDictionary(&lt;span style="color:Blue;"&gt;bool&lt;/span&gt; includeAutoSelected = &lt;span style="color:Blue;"&gt;true&lt;/span&gt;)
}
&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;Also, we wanted to free the OData formatter from having to look at the $select and $expand options. To support that, the wrapper class should contain information about three things,
&lt;ol&gt;&lt;li&gt;what structural properties/navigation properties have to be serialized.&lt;/li&gt;
&lt;li&gt;what actions have to be included in the response.&lt;/li&gt;
&lt;li&gt;what navigation properties have to be expanded.&lt;/li&gt;&lt;/ol&gt;
&lt;br /&gt;To support that the wrapper should also implement the IEdmStructuredObject interface.&lt;br /&gt;&lt;pre&gt;public interface IEdmStructuredObject : IEdmObject
{
        bool TryGetValue(string propertyName, out object value);
}

public interface IEdmObject
{
        IEdmTypeReference GetEdmType();
}&lt;/pre&gt;&lt;br /&gt;The IEdmObject interface is just a way to get the EDM type name required for odata serialization and also provides a dynamic property accessor to separate the implementation of the Wrapper from the formatter. Users who don&amp;#39;t like our Wrapper implementation (geared towards EF and Linq2Objects) could consider doing their own implementations.&lt;br /&gt;
&lt;h4&gt;Generated queries&lt;/h4&gt;There are two things to consider here. &lt;br /&gt;
&lt;ol&gt;&lt;li&gt;OData formatter (in the default case), requires the key properties to generate navigation links. So, even if the client did not ask for key properties explicitly in the request, they have to be fetched from the database. We should probably have an extension point here, so that people who customize link generation can fetch extra properties if they want them for link generation.&lt;/li&gt;
&lt;li&gt;OData formatter requires the type name of the entity while writing responses. If we are getting a partial object from the database (wrapper class), we have to include the type name in the wrapper class. &lt;/li&gt;&lt;/ol&gt;
&lt;br /&gt;&lt;br /&gt;I am listing out the possible generated LINQ queries here for some scenarios for reference. The generated SQL queries (using EF) would be too complex in some cases. If you really want to look at them, refer to the following dump files,
&lt;ol&gt;&lt;li&gt;using Table per hierarchy strategy (TPH) which is code first default - &lt;a href="https://www.codeplex.com/Download?ProjectName=ASPNETWebStack&amp;DownloadId=647202"&gt;tph_dump.txt&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;using table per type strategy (TPT) - &lt;a href="https://www.codeplex.com/Download?ProjectName=ASPNETWebStack&amp;DownloadId=647201"&gt;tpt_dump.txt&lt;/a&gt;&lt;/li&gt;&lt;/ol&gt;
Also, if you are interested in playing around with the sample, I have the cs file &lt;a href="https://www.codeplex.com/Download?ProjectName=ASPNETWebStack&amp;DownloadId=647200"&gt;here&lt;/a&gt;.&lt;br /&gt;
&lt;h6&gt;simple $select&lt;/h6&gt;&lt;div style="color:Black;background-color:White;"&gt;&lt;pre&gt;
uri = &lt;span style="color:#A31515;"&gt;&amp;quot;~/Customers?$select=ID&amp;quot;&lt;/span&gt;;
query = customers.Select&amp;lt;Customer, Wrapper&amp;gt;(c =&amp;gt; &lt;span style="color:Blue;"&gt;new&lt;/span&gt; Wrapper&amp;lt;&lt;span style="color:Blue;"&gt;int&lt;/span&gt;&amp;gt;
{
    TypeName = c &lt;span style="color:Blue;"&gt;is&lt;/span&gt; SpecialCustomer ? typeNameSpecialCustomer : typeNameCustomer,
    Name1 = &lt;span style="color:#A31515;"&gt;&amp;quot;ID&amp;quot;&lt;/span&gt;,
    Value1 = c.ID
});
&lt;/pre&gt;&lt;/div&gt;Response:&lt;br /&gt;&lt;pre&gt;{
  &amp;quot;__type&amp;quot;: &amp;quot;NS.Customer&amp;quot;,
  &amp;quot;ID&amp;quot;: 1
}
{
  &amp;quot;__type&amp;quot;: &amp;quot;NS.SpecialCustomer&amp;quot;,
  &amp;quot;ID&amp;quot;: 2
}&lt;/pre&gt;
&lt;h6&gt;simple $expand&lt;/h6&gt;&lt;div style="color:Black;background-color:White;"&gt;&lt;pre&gt;
uri = &lt;span style="color:#A31515;"&gt;&amp;quot;~/Customers?$expand=Orders&amp;quot;&lt;/span&gt;;
query = customers.Select(c =&amp;gt; &lt;span style="color:Blue;"&gt;new&lt;/span&gt; SelectExpandWrapper&amp;lt;Customer&amp;gt;
{
    TypeName = c &lt;span style="color:Blue;"&gt;is&lt;/span&gt; SpecialCustomer ? typeNameSpecialCustomer : typeNameCustomer,
    Instance = c,
    PropertyContainer = &lt;span style="color:Blue;"&gt;new&lt;/span&gt; NamedProperty&amp;lt;Order&amp;gt;
    {
        Name = &lt;span style="color:#A31515;"&gt;&amp;quot;Orders&amp;quot;&lt;/span&gt;,
        Value = c.Orders.Select(o =&amp;gt; &lt;span style="color:Blue;"&gt;new&lt;/span&gt; SelectExpandWrapper
        {
            TypeName = o &lt;span style="color:Blue;"&gt;is&lt;/span&gt; SpecialOrder ? typeNameSpecialOrder : typeNameOrder,
            Instance = o
        })
    }
});
&lt;/pre&gt;&lt;/div&gt;Response:&lt;br /&gt;&lt;pre&gt;{
  &amp;quot;__type&amp;quot;: &amp;quot;NS.Customer&amp;quot;,
  &amp;quot;ID&amp;quot;: 1,
  &amp;quot;Name&amp;quot;: &amp;quot;Raghu&amp;quot;,
  &amp;quot;Orders&amp;quot;: [
    {
      &amp;quot;__type&amp;quot;: &amp;quot;NS.Order&amp;quot;,
      &amp;quot;ID&amp;quot;: 1,
      &amp;quot;Amount&amp;quot;: 400
    }
  ]
}
{
  &amp;quot;__type&amp;quot;: &amp;quot;NS.SpecialCustomer&amp;quot;,
  &amp;quot;ID&amp;quot;: 2,
  &amp;quot;Name&amp;quot;: &amp;quot;Ram&amp;quot;,
  &amp;quot;Orders&amp;quot;: [
    {
      &amp;quot;__type&amp;quot;: &amp;quot;NS.Order&amp;quot;,
      &amp;quot;ID&amp;quot;: 2,
      &amp;quot;Amount&amp;quot;: 1000
    }
  ]
}&lt;/pre&gt;
&lt;h6&gt;simple $select and $expand&lt;/h6&gt;&lt;div style="color:Black;background-color:White;"&gt;&lt;pre&gt;
uri = &lt;span style="color:#A31515;"&gt;&amp;quot;~/Customers?$select=Name,Orders&amp;amp;$expand=Orders&amp;quot;&lt;/span&gt;;
query = customers.Select(c =&amp;gt; &lt;span style="color:Blue;"&gt;new&lt;/span&gt; SelectExpandWrapper&amp;lt;Customer&amp;gt;
{
    TypeName = c &lt;span style="color:Blue;"&gt;is&lt;/span&gt; SpecialCustomer ? typeNameSpecialCustomer : typeNameCustomer,
    PropertyContainer = &lt;span style="color:Blue;"&gt;new&lt;/span&gt; NamedProperty&amp;lt;&lt;span style="color:Blue;"&gt;string&lt;/span&gt;&amp;gt; 
    {
        Name = &lt;span style="color:#A31515;"&gt;&amp;quot;Name&amp;quot;&lt;/span&gt;,
        Value = c.Name,
        Next = &lt;span style="color:Blue;"&gt;new&lt;/span&gt; NamedProperty&amp;lt;IEnumerable&amp;lt;Order&amp;gt;&amp;gt;
        {
            Name = &lt;span style="color:#A31515;"&gt;&amp;quot;Orders&amp;quot;&lt;/span&gt;,
            Value = c.Orders.Select&amp;lt;Order, Wrapper&amp;gt;(o =&amp;gt; &lt;span style="color:Blue;"&gt;new&lt;/span&gt; Wrapper
            {
                TypeName = o &lt;span style="color:Blue;"&gt;is&lt;/span&gt; SpecialOrder ? typeNameSpecialOrder : typeNameOrder
                Instance = o
            }
        })
    }
});
&lt;/pre&gt;&lt;/div&gt;&lt;pre&gt;Response:
{
  &amp;quot;__type&amp;quot;: &amp;quot;NS.Customer&amp;quot;,
  &amp;quot;Name&amp;quot;: &amp;quot;Raghu&amp;quot;,
  &amp;quot;Orders&amp;quot;: [
    {
      &amp;quot;__type&amp;quot;: &amp;quot;NS.Order&amp;quot;,
      &amp;quot;ID&amp;quot;: 1,
      &amp;quot;Amount&amp;quot;: 400
    }
  ]
}
{
  &amp;quot;__type&amp;quot;: &amp;quot;NS.SpecialCustomer&amp;quot;,
  &amp;quot;Name&amp;quot;: &amp;quot;Ram&amp;quot;,
  &amp;quot;Orders&amp;quot;: [
    {
      &amp;quot;__type&amp;quot;: &amp;quot;NS.Order&amp;quot;,
      &amp;quot;ID&amp;quot;: 2,
      &amp;quot;Amount&amp;quot;: 1000
    }
  ]
}&lt;/pre&gt;&lt;h6&gt;selecting properties from expanded results&lt;/h6&gt;&lt;div style="color:Black;background-color:White;"&gt;&lt;pre&gt;
uri = &lt;span style="color:#A31515;"&gt;&amp;quot;~/Customers?$select=Name,Orders/ID,Orders/Amount&amp;amp;$expand=Orders&amp;quot;&lt;/span&gt;;
query = customers.Select(c =&amp;gt; &lt;span style="color:Blue;"&gt;new&lt;/span&gt; SelectExpandWrapper
{
    TypeName = c &lt;span style="color:Blue;"&gt;is&lt;/span&gt; SpecialCustomer ? typeNameSpecialCustomer : typeNameCustomer,
    PropertyContainer = &lt;span style="color:Blue;"&gt;new&lt;/span&gt; NamedProperty&amp;lt;&lt;span style="color:Blue;"&gt;string&lt;/span&gt;&amp;gt;
    {
        Name = &lt;span style="color:#A31515;"&gt;&amp;quot;Name&amp;quot;&lt;/span&gt;,
        Value = c.Name,
        Next = &lt;span style="color:Blue;"&gt;new&lt;/span&gt; NamedProperty&amp;lt;IEnumerable&amp;lt;SelectExpandWrapper&amp;lt;Order&amp;gt;&amp;gt;&amp;gt;
        {
            Name = &lt;span style="color:#A31515;"&gt;&amp;quot;Orders&amp;quot;&lt;/span&gt;,
            Value = c.Orders(o =&amp;gt; &lt;span style="color:Blue;"&gt;new&lt;/span&gt; SelectExpandWrapper&amp;lt;Order&amp;gt;
            {
                TypeName = o &lt;span style="color:Blue;"&gt;is&lt;/span&gt; SpecialOrder ? typeNameSpecialOrder : typeNameOrder,
                PropertyContainer = &lt;span style="color:Blue;"&gt;new&lt;/span&gt; NamedProperty&amp;lt;&lt;span style="color:Blue;"&gt;int&lt;/span&gt;&amp;gt;
                {
                    Name = &lt;span style="color:#A31515;"&gt;&amp;quot;ID&amp;quot;&lt;/span&gt;,
                    Value = o.ID,
                    Next = &lt;span style="color:Blue;"&gt;new&lt;/span&gt; NamedProperty&amp;lt;&lt;span style="color:Blue;"&gt;int&lt;/span&gt;&amp;gt; 
                    {
                        Name = &lt;span style="color:#A31515;"&gt;&amp;quot;Amount&amp;quot;&lt;/span&gt;,
                        Value = o.Amount
                    }
                }
            }
    })
});
&lt;/pre&gt;&lt;/div&gt;Response:&lt;br /&gt;&lt;pre&gt;{
  &amp;quot;__type&amp;quot;: &amp;quot;NS.Customer&amp;quot;,
  &amp;quot;Name&amp;quot;: &amp;quot;Raghu&amp;quot;,
  &amp;quot;Orders&amp;quot;: [
    {
      &amp;quot;__type&amp;quot;: &amp;quot;NS.Order&amp;quot;,
      &amp;quot;ID&amp;quot;: 1,
      &amp;quot;Amount&amp;quot;: 400
    }
  ]
}
{
  &amp;quot;__type&amp;quot;: &amp;quot;NS.SpecialCustomer&amp;quot;,
  &amp;quot;Name&amp;quot;: &amp;quot;Ram&amp;quot;,
  &amp;quot;Orders&amp;quot;: [
    {
      &amp;quot;__type&amp;quot;: &amp;quot;NS.Order&amp;quot;,
      &amp;quot;ID&amp;quot;: 2,
      &amp;quot;Amount&amp;quot;: 1000
    }
  ]
}&lt;/pre&gt;
&lt;h6&gt;expanding properties on derived types&lt;/h6&gt;&lt;div style="color:Black;background-color:White;"&gt;&lt;pre&gt;
uri = &lt;span style="color:#A31515;"&gt;&amp;quot;~/Customers?$expand=NS.SpecialCustomer/SpecialOrders&amp;quot;&lt;/span&gt;;
query = customers.Select&amp;lt;Customer, Wrapper&amp;gt;(c =&amp;gt; &lt;span style="color:Blue;"&gt;new&lt;/span&gt; Wrapper&amp;lt;IEnumerable&amp;lt;Wrapper&amp;gt;&amp;gt;
{
    TypeName = c &lt;span style="color:Blue;"&gt;is&lt;/span&gt; SpecialCustomer ? typeNameSpecialCustomer : typeNameCustomer,
    AllStrucuturalProperties = &lt;span style="color:#A31515;"&gt;&amp;quot;ID,Name&amp;quot;&lt;/span&gt;,
    Instance = c,
    Name1 = c &lt;span style="color:Blue;"&gt;is&lt;/span&gt; SpecialCustomer ? &lt;span style="color:#A31515;"&gt;&amp;quot;SpecialOrders&amp;quot;&lt;/span&gt; : &lt;span style="color:Blue;"&gt;null&lt;/span&gt;,
    Value1 = (c &lt;span style="color:Blue;"&gt;as&lt;/span&gt; SpecialCustomer).Orders.Select&amp;lt;Order, Wrapper&amp;gt;(o =&amp;gt; &lt;span style="color:Blue;"&gt;new&lt;/span&gt; Wrapper
    {
        TypeName = o &lt;span style="color:Blue;"&gt;is&lt;/span&gt; SpecialOrder ? typeNameSpecialOrder : typeNameOrder,
        AllStrucuturalProperties = &lt;span style="color:#A31515;"&gt;&amp;quot;ID,Amount&amp;quot;&lt;/span&gt;,
        Instance = o
    }) &lt;span style="color:Green;"&gt;//requires null propagation. also don&amp;#39;t confuse null and non-existence&lt;/span&gt;
});
&lt;/pre&gt;&lt;/div&gt;Response:&lt;br /&gt;&lt;pre&gt;{
  &amp;quot;__type&amp;quot;: &amp;quot;NS.Customer&amp;quot;,
  &amp;quot;ID&amp;quot;: 1,
  &amp;quot;Name&amp;quot;: &amp;quot;Raghu&amp;quot;
}
{
  &amp;quot;__type&amp;quot;: &amp;quot;NS.SpecialCustomer&amp;quot;,
  &amp;quot;ID&amp;quot;: 2,
  &amp;quot;Name&amp;quot;: &amp;quot;Ram&amp;quot;,
  &amp;quot;SpecialOrders&amp;quot;: [
    {
      &amp;quot;__type&amp;quot;: &amp;quot;NS.Order&amp;quot;,
      &amp;quot;ID&amp;quot;: 2,
      &amp;quot;Amount&amp;quot;: 1000
    }
  ]
}&lt;/pre&gt;
&lt;h6&gt;selecting properties on derived types&lt;/h6&gt;&lt;div style="color:Black;background-color:White;"&gt;&lt;pre&gt;
uri = &lt;span style="color:#A31515;"&gt;&amp;quot;~/Customers?$select=Name,NS.SpecialCustomer/SpecialCustomerProperty&amp;quot;&lt;/span&gt;;
query = customers.Select&amp;lt;Customer, Wrapper&amp;gt;(c =&amp;gt; &lt;span style="color:Blue;"&gt;new&lt;/span&gt; Wrapper&amp;lt;&lt;span style="color:Blue;"&gt;string&lt;/span&gt;, &lt;span style="color:Blue;"&gt;int&lt;/span&gt;?&amp;gt;
{
    TypeName = c &lt;span style="color:Blue;"&gt;is&lt;/span&gt; SpecialCustomer ? typeNameSpecialCustomer : typeNameCustomer,
    Name1 = &lt;span style="color:#A31515;"&gt;&amp;quot;Name&amp;quot;&lt;/span&gt;,
    Value1 = c.Name,
    &lt;span style="color:Green;"&gt;// requires null propagation. also don&amp;#39;t confuse null and non-existence. If the property name is null, property is non &lt;/span&gt;
    Name2 = c &lt;span style="color:Blue;"&gt;is&lt;/span&gt; SpecialCustomer ? &lt;span style="color:#A31515;"&gt;&amp;quot;SpecialCustomerProperty&amp;quot;&lt;/span&gt; : &lt;span style="color:Blue;"&gt;null&lt;/span&gt;,
    Value2 = (c &lt;span style="color:Blue;"&gt;as&lt;/span&gt; SpecialCustomer).SpecialCustomerProperty &lt;span style="color:Green;"&gt;// notice the int? - required because materializer fails without it&lt;/span&gt;
});
&lt;/pre&gt;&lt;/div&gt;Response:&lt;br /&gt;&lt;pre&gt;{
  &amp;quot;__type&amp;quot;: &amp;quot;NS.Customer&amp;quot;,
  &amp;quot;Name&amp;quot;: &amp;quot;Raghu&amp;quot;
}
{
  &amp;quot;__type&amp;quot;: &amp;quot;NS.SpecialCustomer&amp;quot;,
  &amp;quot;Name&amp;quot;: &amp;quot;Ram&amp;quot;,
  &amp;quot;SpecialCustomerProperty&amp;quot;: 42
}&lt;/pre&gt;
&lt;h6&gt;expanding properties on expanded derived types&lt;/h6&gt;&lt;div style="color:Black;background-color:White;"&gt;&lt;pre&gt;
uri = &lt;span style="color:#A31515;"&gt;&amp;quot;~/Customers?$select=Name&amp;amp;$expand=Orders,Orders/NS.SpecialOrder/SpecialCustomer&amp;quot;&lt;/span&gt;;
query = customers.Select&amp;lt;Customer, Wrapper&amp;gt;(c =&amp;gt; &lt;span style="color:Blue;"&gt;new&lt;/span&gt; Wrapper&amp;lt;&lt;span style="color:Blue;"&gt;string&lt;/span&gt;, IEnumerable&amp;lt;Wrapper&amp;gt;&amp;gt;
{
    TypeName = c &lt;span style="color:Blue;"&gt;is&lt;/span&gt; SpecialCustomer ? typeNameSpecialCustomer : typeNameCustomer,
    Name1 = &lt;span style="color:#A31515;"&gt;&amp;quot;Name&amp;quot;&lt;/span&gt;,
    Value1 = c.Name,
    Name2 = &lt;span style="color:#A31515;"&gt;&amp;quot;Orders&amp;quot;&lt;/span&gt;,
    Value2 = c.Orders.Select&amp;lt;Order, Wrapper&amp;gt;(o =&amp;gt; &lt;span style="color:Blue;"&gt;new&lt;/span&gt; Wrapper&amp;lt;Wrapper&amp;gt;
    {
        AllStrucuturalProperties = &lt;span style="color:#A31515;"&gt;&amp;quot;ID,Amount&amp;quot;&lt;/span&gt;,
        Instance = o,
        Name1 = o &lt;span style="color:Blue;"&gt;is&lt;/span&gt; SpecialOrder ? &lt;span style="color:#A31515;"&gt;&amp;quot;SpecialCustomer&amp;quot;&lt;/span&gt; : &lt;span style="color:Blue;"&gt;null&lt;/span&gt;, &lt;span style="color:Green;"&gt;// optional property&lt;/span&gt;
        Value1 = &lt;span style="color:Blue;"&gt;new&lt;/span&gt; Wrapper
        {
            TypeName = (o &lt;span style="color:Blue;"&gt;as&lt;/span&gt; SpecialOrder).SpecialCustomer &lt;span style="color:Blue;"&gt;is&lt;/span&gt; SpecialCustomer ? typeNameSpecialCustomer : typeNameCustomer,
            AllStrucuturalProperties = &lt;span style="color:#A31515;"&gt;&amp;quot;ID,Name,SpecialCustomerProperty&amp;quot;&lt;/span&gt;,
            Instance = (o &lt;span style="color:Blue;"&gt;as&lt;/span&gt; SpecialOrder).SpecialCustomer
        }
    })
});
&lt;/pre&gt;&lt;/div&gt;Response:&lt;br /&gt;&lt;pre&gt;{
  &amp;quot;__type&amp;quot;: &amp;quot;NS.Customer&amp;quot;,
  &amp;quot;Name&amp;quot;: &amp;quot;Raghu&amp;quot;,
  &amp;quot;Orders&amp;quot;: [
    {
      &amp;quot;__type&amp;quot;: null,
      &amp;quot;ID&amp;quot;: 1,
      &amp;quot;Amount&amp;quot;: 400
    }
  ]
}
{
  &amp;quot;__type&amp;quot;: &amp;quot;NS.SpecialCustomer&amp;quot;,
  &amp;quot;Name&amp;quot;: &amp;quot;Ram&amp;quot;,
  &amp;quot;Orders&amp;quot;: [
    {
      &amp;quot;__type&amp;quot;: null,
      &amp;quot;ID&amp;quot;: 2,
      &amp;quot;Amount&amp;quot;: 1000,
      &amp;quot;SpecialCustomer&amp;quot;: {
        &amp;quot;__type&amp;quot;: &amp;quot;NS.SpecialCustomer&amp;quot;,
        &amp;quot;ID&amp;quot;: 2,
        &amp;quot;Name&amp;quot;: &amp;quot;Ram&amp;quot;,
        &amp;quot;SpecialCustomerProperty&amp;quot;: 42
      }
    }
  ]
}&lt;/pre&gt;&lt;/div&gt;&lt;div class="ClearBoth"&gt;&lt;/div&gt;</description><author>raghuramn</author><pubDate>Thu, 09 May 2013 20:18:23 GMT</pubDate><guid isPermaLink="false">Updated Wiki: $select and $expand support 20130509081823P</guid></item><item><title>Updated Wiki: $select and $expand support</title><link>https://aspnetwebstack.codeplex.com/wikipage?title=$select and $expand support&amp;version=23</link><description>&lt;div class="wikidoc"&gt;&lt;h1&gt;$select and $expand support&lt;/h1&gt;&lt;hr /&gt;
The $select system query option allows clients to requests a limited set of information for each entity or complex type identified by the ResourcePath and other System Query Options like $filter, $top, $skip etc. The $select query option is often used in conjunction with the $expand query option, to first increase the scope of the resource graph returned ($expand) and then selectively prune that resource graph ($select).&lt;br /&gt;&lt;br /&gt;The $expand system query option allows clients to request related resources when a resource that satisfies a particular request is retrieved.&lt;br /&gt;&lt;br /&gt;The following model would be used for the rest of the scenarios,&lt;br /&gt;&lt;br /&gt;&lt;div style="color:Black;background-color:White;"&gt;&lt;pre&gt;
&lt;span style="color:Blue;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;"&gt;class&lt;/span&gt; Customer
{
    &lt;span style="color:Blue;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;"&gt;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&lt;/span&gt; &lt;span style="color:Blue;"&gt;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:Blue;"&gt;virtual&lt;/span&gt; ICollection&amp;lt;Order&amp;gt; Orders { &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:Blue;"&gt;class&lt;/span&gt; SpecialCustomer : Customer
{
    &lt;span style="color:Blue;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;"&gt;int&lt;/span&gt; SpecialCustomerProperty { &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:Blue;"&gt;virtual&lt;/span&gt; ICollection&amp;lt;SpecialOrder&amp;gt; SpecialOrders { &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:Blue;"&gt;class&lt;/span&gt; Order
{
    &lt;span style="color:Blue;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;"&gt;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&lt;/span&gt; &lt;span style="color:Blue;"&gt;int&lt;/span&gt; Amount { &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; Customer Customer { &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:Blue;"&gt;class&lt;/span&gt; SpecialOrder : Order
{
    &lt;span style="color:Blue;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;"&gt;int&lt;/span&gt; SpecialOrderProperty { &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:Blue;"&gt;virtual&lt;/span&gt; SpecialCustomer SpecialCustomer { &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;private&lt;/span&gt; &lt;span style="color:Blue;"&gt;static&lt;/span&gt; IEdmModel GetModel()
{
    ODataConventionModelBuilder builder = &lt;span style="color:Blue;"&gt;new&lt;/span&gt; ODataConventionModelBuilder();
    builder.EntitySet&amp;lt;Customer&amp;gt;(&lt;span style="color:#A31515;"&gt;&amp;quot;Customers&amp;quot;&lt;/span&gt;);
    builder.EntitySet&amp;lt;Order&amp;gt;(&lt;span style="color:#A31515;"&gt;&amp;quot;Orders&amp;quot;&lt;/span&gt;);
    &lt;span style="color:Blue;"&gt;return&lt;/span&gt; builder.GetEdmModel();
}
&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;For example, assuming that a service exposes two entity sets ‘Customers’ and ‘Orders’ and a customer has 1..* (one-to-many) relationship with order, the following URL’s are valid,&lt;br /&gt;
&lt;h3&gt;Supported scenarios&lt;/h3&gt;&lt;a href="http://server/Customers?$select=Id,Name"&gt;http://server/Customers?$select=Id,Name&lt;/a&gt; &lt;br /&gt;Response should contain only the properties Id and Name for each customer. Navigation link for the property Orders must not be present in the response.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://server/Customers?$expand=Orders"&gt;http://server/Customers?$expand=Orders&lt;/a&gt; &lt;br /&gt;Response should contain all the properties of Customer for each customer. It should also contain the expanded Orders for each customer along with the navigation link (depending on the metadata level though). The expanded Orders should contain all structural properties of Orders and navigation link for each navigation property on Order.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://server/Customers?$select=Id,Name,Orders&amp;amp;$expand=Orders"&gt;http://server/Customers?$select=Id,Name,Orders&amp;amp;$expand=Orders&lt;/a&gt; &lt;br /&gt;Response should contain properties Id and Name for each customer and expanded Orders. Each expanded Order should contain all the structural properties of order and a navigation link for each navigation property of order.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://server/Customers?$select=Orders/Id&amp;amp;$expand=Orders"&gt;http://server/Customers?$select=Orders/Id&amp;amp;$expand=Orders&lt;/a&gt; &lt;br /&gt;Selection on an expanded property.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://server/Customers?$select=Id,NS.SpecialCustomer/SpecialId"&gt;http://server/Customers?$select=Id,NS.SpecialCustomer/SpecialId&lt;/a&gt; &lt;br /&gt;Response should contain Id property for each customer and also includes the SpecialId property for each special customer. ODataLib uri parser doesn’t support this yet.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://server/Customers?$expand=NS.SpecialCustomer/SpecialOrder"&gt;http://server/Customers?$expand=NS.SpecialCustomer/SpecialOrder&lt;/a&gt; &lt;br /&gt;Response should contain all structural properties and expand the SpecialOrder property for each special customer. A normal customer would have his navigation links as deferred content in the response. ODataLib uri parser doesn’t support this yet.&lt;br /&gt;&lt;br /&gt;
&lt;h3&gt;Not supported scenarios&lt;/h3&gt;&lt;a href="http://server/Customers(42)/Address?$select=City"&gt;http://server/Customers(42)/Address?$select=City&lt;/a&gt;&lt;br /&gt;Selections of complex types is not supported. (OData V4 might have support for it though)&lt;br /&gt;
&lt;h3&gt;Considerations and Open questions&lt;/h3&gt;There are several open questions that have to be discussed and concluded.
&lt;h4&gt;Support for other formatters&lt;/h4&gt;&lt;ol&gt;&lt;li&gt;Should we support $select with json and xml formatters? $expand is not important as these formatters expand by default. &lt;/li&gt;
&lt;li&gt;Should we change the behavior of these formatters to not expand by default if the incoming query contains a $expand clause?&lt;/li&gt;&lt;/ol&gt;
&lt;h4&gt;Query optimizations&lt;/h4&gt;1. Should $select be optimized? 
&lt;ul&gt;&lt;li&gt;$select is a shape changing query. From a web API perspective, this would mean that the ObjectContent&amp;lt;T&amp;gt; has to be reconstructed. What would happen to the content headers on the ObjectContent? Should we just do a content-negotiation again and say that any content-type headers set after the action finished and before the QueryableAttribute runs would be lost?&lt;/li&gt;
&lt;li&gt;An un-optimized $select would mean more memory allocation on the database.&lt;/li&gt;&lt;/ul&gt;
&lt;blockquote&gt;&lt;blockquote&gt;&lt;i&gt; design meeting@Mar 28&lt;sup&gt;th&lt;/sup&gt;: First cut, actions returning IQueryable will support $select and $expand as it won&amp;#39;t be a shape changing query anymore. $select will be optimized. &lt;/i&gt;&lt;/blockquote&gt;&lt;/blockquote&gt;
2. $expand has to be optimized.
&lt;ul&gt;&lt;li&gt;Without an optimized $expand no-one would ever use our $expand support unless they are building on top of in-memory IQueryable.&lt;/li&gt;
&lt;li&gt;How would the generated query look like? Should we just support EF or try be compatible with some other providers? (Scoping question).&lt;/li&gt;
&lt;li&gt;If we do it only for EF, what is the extensibility story for custom providers?&lt;/li&gt;&lt;/ul&gt;
&lt;blockquote&gt;&lt;blockquote&gt;&lt;i&gt; design meeting@Mar 28&lt;sup&gt;th&lt;/sup&gt;: work item: update with the queries &lt;/i&gt;&lt;/blockquote&gt;&lt;/blockquote&gt;
3. $select and $expand can be done on a single entity. In these cases there is no IQueryable returned by the action. How can we do query manipulation in this scenario? For example, http://server/Customers(42)?$select=Name maps to an web API action &lt;br /&gt;&lt;span class="codeInline"&gt; public Customer GetCustomer(int key). &lt;/span&gt;&lt;br /&gt;
&lt;h4&gt;PageSize for expanded feeds. &lt;/h4&gt;&lt;ol&gt;&lt;li&gt;How can one specify page size for expanded feeds? WCF DS has a per entity-set configuration knob for page size. Should we follow their model? &lt;/li&gt;&lt;/ol&gt;

&lt;h2&gt;Implementation details&lt;/h2&gt;The idea here is that a selection ($select) results in a LINQ .Select query using a wrapper class (kind of an static anonymous type) as the response. The wrapper class contains the properties that have to be included in the selection. For example, a $select involving a selection having one property uses a wrapper class that looks like this,&lt;br /&gt;&lt;div style="color:Black;background-color:White;"&gt;&lt;pre&gt;
&lt;span style="color:Blue;"&gt;public&lt;/span&gt; &lt;span style="color:Blue;"&gt;class&lt;/span&gt; SelectExpandWrapper&amp;lt;TElement&amp;gt; 
{
    &lt;span style="color:Blue;"&gt;public&lt;/span&gt; PropertyContainer Container { &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;internal&lt;/span&gt; &lt;span style="color:Blue;"&gt;abstract&lt;/span&gt; &lt;span style="color:Blue;"&gt;class&lt;/span&gt; PropertyContainer
{
        &lt;span style="color:Blue;"&gt;public&lt;/span&gt; Dictionary&amp;lt;&lt;span style="color:Blue;"&gt;string&lt;/span&gt;, &lt;span style="color:Blue;"&gt;object&lt;/span&gt;&amp;gt; ToDictionary(&lt;span style="color:Blue;"&gt;bool&lt;/span&gt; includeAutoSelected = &lt;span style="color:Blue;"&gt;true&lt;/span&gt;)
}
&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;Also, we wanted to free the OData formatter from having to look at the $select and $expand options. To support that, the wrapper class should contain information about three things,
&lt;ol&gt;&lt;li&gt;what structural properties/navigation properties have to be serialized.&lt;/li&gt;
&lt;li&gt;what actions have to be included in the response.&lt;/li&gt;
&lt;li&gt;what navigation properties have to be expanded.&lt;/li&gt;&lt;/ol&gt;
&lt;br /&gt;To support that the wrapper should also implement the IEdmStructuredObject interface.&lt;br /&gt;&lt;pre&gt;public interface IEdmStructuredObject : IEdmObject
{
        bool TryGetValue(string propertyName, out object value);
}

public interface IEdmObject
{
        IEdmTypeReference GetEdmType();
}&lt;/pre&gt;&lt;br /&gt;The IEdmObject interface is just a way to get the EDM type name required for odata serialization and also provides a dynamic property accessor to separate the implementation of the Wrapper from the formatter. Users who don&amp;#39;t like our Wrapper implementation (geared towards EF and Linq2Objects) could consider doing their own implementations.&lt;br /&gt;
&lt;h4&gt;Generated queries&lt;/h4&gt;There are two things to consider here. &lt;br /&gt;
&lt;ol&gt;&lt;li&gt;OData formatter (in the default case), requires the key properties to generate navigation links. So, even if the client did not ask for key properties explicitly in the request, they have to be fetched from the database. We should probably have an extension point here, so that people who customize link generation can fetch extra properties if they want them for link generation.&lt;/li&gt;
&lt;li&gt;OData formatter requires the type name of the entity while writing responses. If we are getting a partial object from the database (wrapper class), we have to include the type name in the wrapper class. &lt;/li&gt;&lt;/ol&gt;
&lt;br /&gt;&lt;br /&gt;I am listing out the possible generated LINQ queries here for some scenarios for reference. The generated SQL queries (using EF) would be too complex in some cases. If you really want to look at them, refer to the following dump files,
&lt;ol&gt;&lt;li&gt;using Table per hierarchy strategy (TPH) which is code first default - &lt;a href="https://www.codeplex.com/Download?ProjectName=ASPNETWebStack&amp;DownloadId=647202"&gt;tph_dump.txt&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;using table per type strategy (TPT) - &lt;a href="https://www.codeplex.com/Download?ProjectName=ASPNETWebStack&amp;DownloadId=647201"&gt;tpt_dump.txt&lt;/a&gt;&lt;/li&gt;&lt;/ol&gt;
Also, if you are interested in playing around with the sample, I have the cs file &lt;a href="https://www.codeplex.com/Download?ProjectName=ASPNETWebStack&amp;DownloadId=647200"&gt;here&lt;/a&gt;.&lt;br /&gt;
&lt;h6&gt;simple $select&lt;/h6&gt;&lt;div style="color:Black;background-color:White;"&gt;&lt;pre&gt;
uri = &lt;span style="color:#A31515;"&gt;&amp;quot;~/Customers?$select=ID&amp;quot;&lt;/span&gt;;
query = customers.Select&amp;lt;Customer, Wrapper&amp;gt;(c =&amp;gt; &lt;span style="color:Blue;"&gt;new&lt;/span&gt; Wrapper&amp;lt;&lt;span style="color:Blue;"&gt;int&lt;/span&gt;&amp;gt;
{
    TypeName = c &lt;span style="color:Blue;"&gt;is&lt;/span&gt; SpecialCustomer ? typeNameSpecialCustomer : typeNameCustomer,
    Name1 = &lt;span style="color:#A31515;"&gt;&amp;quot;ID&amp;quot;&lt;/span&gt;,
    Value1 = c.ID
});
&lt;/pre&gt;&lt;/div&gt;Response:&lt;br /&gt;&lt;pre&gt;{
  &amp;quot;__type&amp;quot;: &amp;quot;NS.Customer&amp;quot;,
  &amp;quot;ID&amp;quot;: 1
}
{
  &amp;quot;__type&amp;quot;: &amp;quot;NS.SpecialCustomer&amp;quot;,
  &amp;quot;ID&amp;quot;: 2
}&lt;/pre&gt;
&lt;h6&gt;simple $expand&lt;/h6&gt;&lt;div style="color:Black;background-color:White;"&gt;&lt;pre&gt;
uri = &lt;span style="color:#A31515;"&gt;&amp;quot;~/Customers?$expand=Orders&amp;quot;&lt;/span&gt;;
query = customers.Select&amp;lt;Customer, Wrapper&amp;gt;(c =&amp;gt; &lt;span style="color:Blue;"&gt;new&lt;/span&gt; Wrapper&amp;lt;IEnumerable&amp;lt;Wrapper&amp;gt;&amp;gt;
{
    TypeName = c &lt;span style="color:Blue;"&gt;is&lt;/span&gt; SpecialCustomer ? typeNameSpecialCustomer : typeNameCustomer,
    AllStrucuturalProperties = &lt;span style="color:#A31515;"&gt;&amp;quot;ID,Name&amp;quot;&lt;/span&gt;,
    Instance = c,
    Name1 = &lt;span style="color:#A31515;"&gt;&amp;quot;Orders&amp;quot;&lt;/span&gt;,
    Value1 = c.Orders.Select&amp;lt;Order, Wrapper&amp;gt;(o =&amp;gt; &lt;span style="color:Blue;"&gt;new&lt;/span&gt; Wrapper
    {
        TypeName = o &lt;span style="color:Blue;"&gt;is&lt;/span&gt; SpecialOrder ? typeNameSpecialOrder : typeNameOrder,
        AllStrucuturalProperties = &lt;span style="color:#A31515;"&gt;&amp;quot;ID,Amount&amp;quot;&lt;/span&gt;,
        Instance = o
    })
});
&lt;/pre&gt;&lt;/div&gt;Response:&lt;br /&gt;&lt;pre&gt;{
  &amp;quot;__type&amp;quot;: &amp;quot;NS.Customer&amp;quot;,
  &amp;quot;ID&amp;quot;: 1,
  &amp;quot;Name&amp;quot;: &amp;quot;Raghu&amp;quot;,
  &amp;quot;Orders&amp;quot;: [
    {
      &amp;quot;__type&amp;quot;: &amp;quot;NS.Order&amp;quot;,
      &amp;quot;ID&amp;quot;: 1,
      &amp;quot;Amount&amp;quot;: 400
    }
  ]
}
{
  &amp;quot;__type&amp;quot;: &amp;quot;NS.SpecialCustomer&amp;quot;,
  &amp;quot;ID&amp;quot;: 2,
  &amp;quot;Name&amp;quot;: &amp;quot;Ram&amp;quot;,
  &amp;quot;Orders&amp;quot;: [
    {
      &amp;quot;__type&amp;quot;: &amp;quot;NS.Order&amp;quot;,
      &amp;quot;ID&amp;quot;: 2,
      &amp;quot;Amount&amp;quot;: 1000
    }
  ]
}&lt;/pre&gt;
&lt;h6&gt;simple $select and $expand&lt;/h6&gt;&lt;div style="color:Black;background-color:White;"&gt;&lt;pre&gt;
uri = &lt;span style="color:#A31515;"&gt;&amp;quot;~/Customers?$select=Name,Orders&amp;amp;$expand=Orders&amp;quot;&lt;/span&gt;;
query = customers.Select&amp;lt;Customer, Wrapper&amp;gt;(c =&amp;gt; &lt;span style="color:Blue;"&gt;new&lt;/span&gt; Wrapper&amp;lt;&lt;span style="color:Blue;"&gt;string&lt;/span&gt;, IEnumerable&amp;lt;Wrapper&amp;gt;&amp;gt;
{
    TypeName = c &lt;span style="color:Blue;"&gt;is&lt;/span&gt; SpecialCustomer ? typeNameSpecialCustomer : typeNameCustomer,
    Name1 = &lt;span style="color:#A31515;"&gt;&amp;quot;Name&amp;quot;&lt;/span&gt;,
    Value1 = c.Name,
    Name2 = &lt;span style="color:#A31515;"&gt;&amp;quot;Orders&amp;quot;&lt;/span&gt;,
    Value2 = c.Orders.Select&amp;lt;Order, Wrapper&amp;gt;(o =&amp;gt; &lt;span style="color:Blue;"&gt;new&lt;/span&gt; Wrapper
    {
        TypeName = o &lt;span style="color:Blue;"&gt;is&lt;/span&gt; SpecialOrder ? typeNameSpecialOrder : typeNameOrder
        AllStrucuturalProperties = &lt;span style="color:#A31515;"&gt;&amp;quot;ID,Amount&amp;quot;&lt;/span&gt;,
        Instance = o
    })
});
&lt;/pre&gt;&lt;/div&gt;&lt;pre&gt;Response:
{
  &amp;quot;__type&amp;quot;: &amp;quot;NS.Customer&amp;quot;,
  &amp;quot;Name&amp;quot;: &amp;quot;Raghu&amp;quot;,
  &amp;quot;Orders&amp;quot;: [
    {
      &amp;quot;__type&amp;quot;: &amp;quot;NS.Order&amp;quot;,
      &amp;quot;ID&amp;quot;: 1,
      &amp;quot;Amount&amp;quot;: 400
    }
  ]
}
{
  &amp;quot;__type&amp;quot;: &amp;quot;NS.SpecialCustomer&amp;quot;,
  &amp;quot;Name&amp;quot;: &amp;quot;Ram&amp;quot;,
  &amp;quot;Orders&amp;quot;: [
    {
      &amp;quot;__type&amp;quot;: &amp;quot;NS.Order&amp;quot;,
      &amp;quot;ID&amp;quot;: 2,
      &amp;quot;Amount&amp;quot;: 1000
    }
  ]
}&lt;/pre&gt;&lt;h6&gt;selecting properties from expanded results&lt;/h6&gt;&lt;div style="color:Black;background-color:White;"&gt;&lt;pre&gt;
uri = &lt;span style="color:#A31515;"&gt;&amp;quot;~/Customers?$select=Name,Orders/ID,Orders/Amount&amp;amp;$expand=Orders&amp;quot;&lt;/span&gt;;
query = customers.Select&amp;lt;Customer, Wrapper&amp;gt;(c =&amp;gt; &lt;span style="color:Blue;"&gt;new&lt;/span&gt; Wrapper&amp;lt;&lt;span style="color:Blue;"&gt;string&lt;/span&gt;, IEnumerable&amp;lt;Wrapper&amp;gt;&amp;gt;
{
    TypeName = c &lt;span style="color:Blue;"&gt;is&lt;/span&gt; SpecialCustomer ? typeNameSpecialCustomer : typeNameCustomer,
    Name1 = &lt;span style="color:#A31515;"&gt;&amp;quot;Name&amp;quot;&lt;/span&gt;,
    Value1 = c.Name,
    Name2 = &lt;span style="color:#A31515;"&gt;&amp;quot;Orders&amp;quot;&lt;/span&gt;,
    Value2 = c.Orders.Select&amp;lt;Order, Wrapper&amp;gt;(o =&amp;gt; &lt;span style="color:Blue;"&gt;new&lt;/span&gt; Wrapper&amp;lt;&lt;span style="color:Blue;"&gt;int&lt;/span&gt;, &lt;span style="color:Blue;"&gt;int&lt;/span&gt;&amp;gt;
    {
        TypeName = o &lt;span style="color:Blue;"&gt;is&lt;/span&gt; SpecialOrder ? typeNameSpecialOrder : typeNameOrder,
        Name1 = &lt;span style="color:#A31515;"&gt;&amp;quot;ID&amp;quot;&lt;/span&gt;,
        Name2 = &lt;span style="color:#A31515;"&gt;&amp;quot;Amount&amp;quot;&lt;/span&gt;,
        Value1 = o.ID,
        Value2 = o.Amount
    })
});
&lt;/pre&gt;&lt;/div&gt;Response:&lt;br /&gt;&lt;pre&gt;{
  &amp;quot;__type&amp;quot;: &amp;quot;NS.Customer&amp;quot;,
  &amp;quot;Name&amp;quot;: &amp;quot;Raghu&amp;quot;,
  &amp;quot;Orders&amp;quot;: [
    {
      &amp;quot;__type&amp;quot;: &amp;quot;NS.Order&amp;quot;,
      &amp;quot;ID&amp;quot;: 1,
      &amp;quot;Amount&amp;quot;: 400
    }
  ]
}
{
  &amp;quot;__type&amp;quot;: &amp;quot;NS.SpecialCustomer&amp;quot;,
  &amp;quot;Name&amp;quot;: &amp;quot;Ram&amp;quot;,
  &amp;quot;Orders&amp;quot;: [
    {
      &amp;quot;__type&amp;quot;: &amp;quot;NS.Order&amp;quot;,
      &amp;quot;ID&amp;quot;: 2,
      &amp;quot;Amount&amp;quot;: 1000
    }
  ]
}&lt;/pre&gt;
&lt;h6&gt;expanding properties on derived types&lt;/h6&gt;&lt;div style="color:Black;background-color:White;"&gt;&lt;pre&gt;
uri = &lt;span style="color:#A31515;"&gt;&amp;quot;~/Customers?$expand=NS.SpecialCustomer/SpecialOrders&amp;quot;&lt;/span&gt;;
query = customers.Select&amp;lt;Customer, Wrapper&amp;gt;(c =&amp;gt; &lt;span style="color:Blue;"&gt;new&lt;/span&gt; Wrapper&amp;lt;IEnumerable&amp;lt;Wrapper&amp;gt;&amp;gt;
{
    TypeName = c &lt;span style="color:Blue;"&gt;is&lt;/span&gt; SpecialCustomer ? typeNameSpecialCustomer : typeNameCustomer,
    AllStrucuturalProperties = &lt;span style="color:#A31515;"&gt;&amp;quot;ID,Name&amp;quot;&lt;/span&gt;,
    Instance = c,
    Name1 = c &lt;span style="color:Blue;"&gt;is&lt;/span&gt; SpecialCustomer ? &lt;span style="color:#A31515;"&gt;&amp;quot;SpecialOrders&amp;quot;&lt;/span&gt; : &lt;span style="color:Blue;"&gt;null&lt;/span&gt;,
    Value1 = (c &lt;span style="color:Blue;"&gt;as&lt;/span&gt; SpecialCustomer).Orders.Select&amp;lt;Order, Wrapper&amp;gt;(o =&amp;gt; &lt;span style="color:Blue;"&gt;new&lt;/span&gt; Wrapper
    {
        TypeName = o &lt;span style="color:Blue;"&gt;is&lt;/span&gt; SpecialOrder ? typeNameSpecialOrder : typeNameOrder,
        AllStrucuturalProperties = &lt;span style="color:#A31515;"&gt;&amp;quot;ID,Amount&amp;quot;&lt;/span&gt;,
        Instance = o
    }) &lt;span style="color:Green;"&gt;//requires null propagation. also don&amp;#39;t confuse null and non-existence&lt;/span&gt;
});
&lt;/pre&gt;&lt;/div&gt;Response:&lt;br /&gt;&lt;pre&gt;{
  &amp;quot;__type&amp;quot;: &amp;quot;NS.Customer&amp;quot;,
  &amp;quot;ID&amp;quot;: 1,
  &amp;quot;Name&amp;quot;: &amp;quot;Raghu&amp;quot;
}
{
  &amp;quot;__type&amp;quot;: &amp;quot;NS.SpecialCustomer&amp;quot;,
  &amp;quot;ID&amp;quot;: 2,
  &amp;quot;Name&amp;quot;: &amp;quot;Ram&amp;quot;,
  &amp;quot;SpecialOrders&amp;quot;: [
    {
      &amp;quot;__type&amp;quot;: &amp;quot;NS.Order&amp;quot;,
      &amp;quot;ID&amp;quot;: 2,
      &amp;quot;Amount&amp;quot;: 1000
    }
  ]
}&lt;/pre&gt;
&lt;h6&gt;selecting properties on derived types&lt;/h6&gt;&lt;div style="color:Black;background-color:White;"&gt;&lt;pre&gt;
uri = &lt;span style="color:#A31515;"&gt;&amp;quot;~/Customers?$select=Name,NS.SpecialCustomer/SpecialCustomerProperty&amp;quot;&lt;/span&gt;;
query = customers.Select&amp;lt;Customer, Wrapper&amp;gt;(c =&amp;gt; &lt;span style="color:Blue;"&gt;new&lt;/span&gt; Wrapper&amp;lt;&lt;span style="color:Blue;"&gt;string&lt;/span&gt;, &lt;span style="color:Blue;"&gt;int&lt;/span&gt;?&amp;gt;
{
    TypeName = c &lt;span style="color:Blue;"&gt;is&lt;/span&gt; SpecialCustomer ? typeNameSpecialCustomer : typeNameCustomer,
    Name1 = &lt;span style="color:#A31515;"&gt;&amp;quot;Name&amp;quot;&lt;/span&gt;,
    Value1 = c.Name,
    &lt;span style="color:Green;"&gt;// requires null propagation. also don&amp;#39;t confuse null and non-existence. If the property name is null, property is non &lt;/span&gt;
    Name2 = c &lt;span style="color:Blue;"&gt;is&lt;/span&gt; SpecialCustomer ? &lt;span style="color:#A31515;"&gt;&amp;quot;SpecialCustomerProperty&amp;quot;&lt;/span&gt; : &lt;span style="color:Blue;"&gt;null&lt;/span&gt;,
    Value2 = (c &lt;span style="color:Blue;"&gt;as&lt;/span&gt; SpecialCustomer).SpecialCustomerProperty &lt;span style="color:Green;"&gt;// notice the int? - required because materializer fails without it&lt;/span&gt;
});
&lt;/pre&gt;&lt;/div&gt;Response:&lt;br /&gt;&lt;pre&gt;{
  &amp;quot;__type&amp;quot;: &amp;quot;NS.Customer&amp;quot;,
  &amp;quot;Name&amp;quot;: &amp;quot;Raghu&amp;quot;
}
{
  &amp;quot;__type&amp;quot;: &amp;quot;NS.SpecialCustomer&amp;quot;,
  &amp;quot;Name&amp;quot;: &amp;quot;Ram&amp;quot;,
  &amp;quot;SpecialCustomerProperty&amp;quot;: 42
}&lt;/pre&gt;
&lt;h6&gt;expanding properties on expanded derived types&lt;/h6&gt;&lt;div style="color:Black;background-color:White;"&gt;&lt;pre&gt;
uri = &lt;span style="color:#A31515;"&gt;&amp;quot;~/Customers?$select=Name&amp;amp;$expand=Orders,Orders/NS.SpecialOrder/SpecialCustomer&amp;quot;&lt;/span&gt;;
query = customers.Select&amp;lt;Customer, Wrapper&amp;gt;(c =&amp;gt; &lt;span style="color:Blue;"&gt;new&lt;/span&gt; Wrapper&amp;lt;&lt;span style="color:Blue;"&gt;string&lt;/span&gt;, IEnumerable&amp;lt;Wrapper&amp;gt;&amp;gt;
{
    TypeName = c &lt;span style="color:Blue;"&gt;is&lt;/span&gt; SpecialCustomer ? typeNameSpecialCustomer : typeNameCustomer,
    Name1 = &lt;span style="color:#A31515;"&gt;&amp;quot;Name&amp;quot;&lt;/span&gt;,
    Value1 = c.Name,
    Name2 = &lt;span style="color:#A31515;"&gt;&amp;quot;Orders&amp;quot;&lt;/span&gt;,
    Value2 = c.Orders.Select&amp;lt;Order, Wrapper&amp;gt;(o =&amp;gt; &lt;span style="color:Blue;"&gt;new&lt;/span&gt; Wrapper&amp;lt;Wrapper&amp;gt;
    {
        AllStrucuturalProperties = &lt;span style="color:#A31515;"&gt;&amp;quot;ID,Amount&amp;quot;&lt;/span&gt;,
        Instance = o,
        Name1 = o &lt;span style="color:Blue;"&gt;is&lt;/span&gt; SpecialOrder ? &lt;span style="color:#A31515;"&gt;&amp;quot;SpecialCustomer&amp;quot;&lt;/span&gt; : &lt;span style="color:Blue;"&gt;null&lt;/span&gt;, &lt;span style="color:Green;"&gt;// optional property&lt;/span&gt;
        Value1 = &lt;span style="color:Blue;"&gt;new&lt;/span&gt; Wrapper
        {
            TypeName = (o &lt;span style="color:Blue;"&gt;as&lt;/span&gt; SpecialOrder).SpecialCustomer &lt;span style="color:Blue;"&gt;is&lt;/span&gt; SpecialCustomer ? typeNameSpecialCustomer : typeNameCustomer,
            AllStrucuturalProperties = &lt;span style="color:#A31515;"&gt;&amp;quot;ID,Name,SpecialCustomerProperty&amp;quot;&lt;/span&gt;,
            Instance = (o &lt;span style="color:Blue;"&gt;as&lt;/span&gt; SpecialOrder).SpecialCustomer
        }
    })
});
&lt;/pre&gt;&lt;/div&gt;Response:&lt;br /&gt;&lt;pre&gt;{
  &amp;quot;__type&amp;quot;: &amp;quot;NS.Customer&amp;quot;,
  &amp;quot;Name&amp;quot;: &amp;quot;Raghu&amp;quot;,
  &amp;quot;Orders&amp;quot;: [
    {
      &amp;quot;__type&amp;quot;: null,
      &amp;quot;ID&amp;quot;: 1,
      &amp;quot;Amount&amp;quot;: 400
    }
  ]
}
{
  &amp;quot;__type&amp;quot;: &amp;quot;NS.SpecialCustomer&amp;quot;,
  &amp;quot;Name&amp;quot;: &amp;quot;Ram&amp;quot;,
  &amp;quot;Orders&amp;quot;: [
    {
      &amp;quot;__type&amp;quot;: null,
      &amp;quot;ID&amp;quot;: 2,
      &amp;quot;Amount&amp;quot;: 1000,
      &amp;quot;SpecialCustomer&amp;quot;: {
        &amp;quot;__type&amp;quot;: &amp;quot;NS.SpecialCustomer&amp;quot;,
        &amp;quot;ID&amp;quot;: 2,
        &amp;quot;Name&amp;quot;: &amp;quot;Ram&amp;quot;,
        &amp;quot;SpecialCustomerProperty&amp;quot;: 42
      }
    }
  ]
}&lt;/pre&gt;&lt;/div&gt;&lt;div class="ClearBoth"&gt;&lt;/div&gt;</description><author>raghuramn</author><pubDate>Thu, 09 May 2013 16:30:42 GMT</pubDate><guid isPermaLink="false">Updated Wiki: $select and $expand support 20130509043042P</guid></item><item><title>New Comment on "CORS support for ASP.NET Web API"</title><link>https://aspnetwebstack.codeplex.com/wikipage?title=CORS support for ASP.NET Web API&amp;ANCHOR#C27434</link><description>Excited when it will be part of WEB API..</description><author>ramnaresh_t</author><pubDate>Thu, 09 May 2013 16:10:13 GMT</pubDate><guid isPermaLink="false">New Comment on "CORS support for ASP.NET Web API" 20130509041013P</guid></item><item><title>New Comment on "Roadmap"</title><link>https://aspnetwebstack.codeplex.com/wikipage?title=Roadmap&amp;ANCHOR#C27394</link><description>Thanks for all the hard work&amp;#33; I&amp;#39;m really glad that you guys are trying to simplify the use of DropDownLists, Its a real pain in the ass to make it work, and not allot of helpful tutorials and info on it. And very smart move to integrate twitter bootstrap&amp;#33;&amp;#10;&amp;#10;This is why I love to be a .net developer &amp;#61;&amp;#41;</description><author>Rujaun</author><pubDate>Sun, 05 May 2013 18:26:28 GMT</pubDate><guid isPermaLink="false">New Comment on "Roadmap" 20130505062628P</guid></item><item><title>New Comment on "Roadmap"</title><link>https://aspnetwebstack.codeplex.com/wikipage?title=Roadmap&amp;ANCHOR#C27393</link><description>Thanks for all the hard work&amp;#33; I&amp;#39;m really glad that you guys are trying to simplify the use of DropDownLists, Its a real pain in the ass to make it work, and not allot of helpful tutorials and info on it. And very smart move to integrate twitter bootstrap&amp;#33;&amp;#10;&amp;#10;This is why I like to be a .net developer &amp;#61;&amp;#41;</description><author>Rujaun</author><pubDate>Sun, 05 May 2013 18:25:23 GMT</pubDate><guid isPermaLink="false">New Comment on "Roadmap" 20130505062523P</guid></item><item><title>New Comment on "Attribute routing in Web API"</title><link>https://aspnetwebstack.codeplex.com/wikipage?title=Attribute routing in Web API&amp;ANCHOR#C27335</link><description>&amp;#34;Give a rope to people, they will hang themselves up with it&amp;#34; - anonymous&amp;#10;&amp;#10;I have meant to write this comment weeks before but been busy and I hope it is not too late. Just fresh from finding a big performance bottleneck which turned out to be due to AttributeRouting, I think it is time to say a few words.&amp;#10;&amp;#10;Routing is an area which needs improvement but the direction taken by adopting AttributeRouting is the opposite of what is needed. So instead of decentralising routes and hide the valuable information in string tokens, we need to move towards not only centralising the routing &amp;#40;as it is a strategic application-wide decision&amp;#41; but to allow the routes to be defined with zero configuration by the resources. And also the relationships to be defined naturally by the resources. So I believe it is definitely more like Darrel Miller&amp;#39;s ApiRouter rather than AttributeRouting. &amp;#10;&amp;#10;Another aspect is the hierarchical routing which also defines the relationships naturally with code rather than arbitrary string tokens. This allows  hypermedia to be derived from the resource itself rather than to hand-coded in the resource. Reality is Web APIs are hierarchical while routing adopted from MVC is very flat. One of the problems is the linear search through the routes definitely does not scale.&amp;#10;&amp;#10;I can do a proof of concept to show what I mean - if you think it is useful.</description><author>aliostad</author><pubDate>Mon, 29 Apr 2013 07:44:40 GMT</pubDate><guid isPermaLink="false">New Comment on "Attribute routing in Web API" 20130429074440A</guid></item><item><title>New Comment on "Attribute routing in Web API"</title><link>https://aspnetwebstack.codeplex.com/wikipage?title=Attribute routing in Web API&amp;ANCHOR#C27334</link><description>&amp;#34;Give a rope to people, they will hang themselves up with it&amp;#34; - anonymous&amp;#10;&amp;#10;I have meant to write this comment weeks before but been busy and I hope it is not too late. Just fresh from finding a big performance bottleneck which turned out to be due to AttributeRouting, I think it is time to say a few words.&amp;#10;&amp;#10;Routing is an area which needs improvement but the direction taken by adopting AttributeRouting is the opposite of what is needed. So instead of decentralising routes and hide the valuable information in string tokens, we need to move towards not only centralising the routing &amp;#40;as it is a strategic application-wide decision&amp;#41; but to allow the routes to be defined with zero configuration by the resources. And also the relationships to be defined naturally by the resources. So I believe it is definitely more like Darrel Miller&amp;#39;s ApiRouter rather than AttributeRouting. &amp;#10;&amp;#10;Another aspect is the hierarchical routing which also defines the relationships naturally with code rather than arbitrary string tokens. This allows  hypermedia to be derived from the resource itself rather than to hand-coded in the resource. Reality is Web APIs are hierarchical while routing adopted from MVC is very flat. One of the problems is the linear search through the routes definitely does not scale.&amp;#10;&amp;#10;I can do a proof of concept to show what I mean - if you think it is useful.</description><author>aliostad</author><pubDate>Mon, 29 Apr 2013 07:39:24 GMT</pubDate><guid isPermaLink="false">New Comment on "Attribute routing in Web API" 20130429073924A</guid></item><item><title>New Comment on "CORS support for ASP.NET Web API"</title><link>https://aspnetwebstack.codeplex.com/wikipage?title=CORS support for ASP.NET Web API&amp;ANCHOR#C27321</link><description>The latest nightlies has parameters on the EnableCorsAttribute. What should I be putting in for origin, headers and methods to make all of them work&amp;#63; &amp;#40;I just want to allow a request from anyone with any method type and any headers.&amp;#41;</description><author>Geminiman</author><pubDate>Fri, 26 Apr 2013 21:22:06 GMT</pubDate><guid isPermaLink="false">New Comment on "CORS support for ASP.NET Web API" 20130426092206P</guid></item><item><title>New Comment on "Attribute routing in Web API"</title><link>https://aspnetwebstack.codeplex.com/wikipage?title=Attribute routing in Web API&amp;ANCHOR#C27319</link><description>The good news is that Tim McCall of AttributeRouting fame is the main contributor to pulling attribute into ASP.NET Web API, which means the design benefits from his extensive expertise. There is no intent to reinvent the API. Instead the goal is to integrate the API right into the runtime so that attribute routing becomes a first class experience &amp;#40;ex. we are integrating directly with the existing HttpGet&amp;#47;Post&amp;#47;Put&amp;#47;Delete attributes instead of creating new ones&amp;#41;. That said, your feedback is critical to ensuring we do our job right, so by all means please grab a daily build and let us know what you think&amp;#33;</description><author>danroth27</author><pubDate>Fri, 26 Apr 2013 17:32:08 GMT</pubDate><guid isPermaLink="false">New Comment on "Attribute routing in Web API" 20130426053208P</guid></item><item><title>New Comment on "Attribute routing in Web API"</title><link>https://aspnetwebstack.codeplex.com/wikipage?title=Attribute routing in Web API&amp;ANCHOR#C27316</link><description>&amp;#34;Give a rope to people, they will hang themselves up with it&amp;#34; - anonymous&amp;#10;&amp;#10;I meant to write this comment weeks before but been busy and I hope it is not too late. Just fresh from finding a big performance bottleneck which turned out to be due to AttributeRouting, I think it is time to say a few words.&amp;#10;&amp;#10;Routing is an area which needs improvement but the direction taken by adopting AttributeRouting is the opposite of what is needed. So instead of decentralising routes and hide the valuable information in string tokens, we need to move towards not only centralising the routing &amp;#40;as it is a strategic application-wide decision&amp;#41; but to allow the routes to be defined with zero configuration by the resources. And also the relationships to be defined naturally by the resources. So I believe it is definitely more like Darrel Miller&amp;#39;s ApiRouter rather than AttributeRouting. &amp;#10;&amp;#10;Another aspect is the hierarchical routing which also defines the relationships naturally with code rather than arbitrary string tokens. This allows  hypermedia to be derived from the resource itself rather than to hand-coded in the resource. Reality is Web APIs are hierarchical while routing adopted from MVC is very flat. One of the problems is the linear search through the routes definitely does not scale.&amp;#10;&amp;#10;I can do a proof of concept to show what I mean - if you think it is useful.</description><author>aliostad</author><pubDate>Fri, 26 Apr 2013 15:59:41 GMT</pubDate><guid isPermaLink="false">New Comment on "Attribute routing in Web API" 20130426035941P</guid></item><item><title>Updated Wiki: Contributors</title><link>https://aspnetwebstack.codeplex.com/wikipage?title=Contributors&amp;version=14</link><description>&lt;div class="wikidoc"&gt;
&lt;p&gt;We would like to thank the following contributors for sharing code and making ASP.NET MVC, Web API and Web Pages better products.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.codeplex.com/site/users/view/migueldeicaza"&gt;Miguel de Icaza&lt;/a&gt;
&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.codeplex.com/site/users/view/Birdchest"&gt;Khalid Abuhakmeh&lt;/a&gt;
&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.codeplex.com/site/users/view/nberardi"&gt;Nick Berardi&lt;/a&gt; &lt;/li&gt;&lt;li&gt;&lt;a href="http://www.codeplex.com/site/users/view/xpaulbettsx"&gt;Paul Betts&lt;/a&gt; &lt;/li&gt;&lt;li&gt;&lt;a href="http://www.codeplex.com/site/users/view/PatrickMcDonald"&gt;Patrick McDonald&lt;/a&gt;
&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.codeplex.com/site/users/view/jbogard"&gt;Jimmy Bogard&lt;/a&gt; &lt;/li&gt;&lt;li&gt;&lt;a href="http://www.codeplex.com/site/users/view/andreazevedo"&gt;Andre Azevedo&lt;/a&gt;
&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.codeplex.com/site/users/view/digitaljeebus"&gt;Joseph Lombrozo&lt;/a&gt;
&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.codeplex.com/site/users/view/harrisonbrock"&gt;Harrison Brock&lt;/a&gt;
&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.codeplex.com/site/users/view/ptaylor"&gt;Perry Taylor&lt;/a&gt; &lt;/li&gt;&lt;li&gt;&lt;a href="http://www.codeplex.com/site/users/view/ssmith"&gt;Steven Smith&lt;/a&gt; &lt;/li&gt;&lt;li&gt;&lt;a href="http://www.codeplex.com/site/users/view/BrockAllen"&gt;Brock Allen&lt;/a&gt; &lt;/li&gt;&lt;li&gt;&lt;a href="http://www.codeplex.com/site/users/view/grantmcdade"&gt;Grant McDade&lt;/a&gt;
&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.codeplex.com/site/users/view/mccalltd"&gt;Timothy McCall&lt;/a&gt;
&lt;/li&gt;&lt;li&gt;&lt;a href="https://www.codeplex.com/site/users/view/bmsullivan"&gt;Brian Sullivan&lt;/a&gt;
&lt;/li&gt;&lt;/ul&gt;
&lt;/div&gt;&lt;div class="ClearBoth"&gt;&lt;/div&gt;</description><author>yaohuang</author><pubDate>Thu, 25 Apr 2013 23:11:49 GMT</pubDate><guid isPermaLink="false">Updated Wiki: Contributors 20130425111149P</guid></item><item><title>New Comment on "Attribute routing in Web API"</title><link>https://aspnetwebstack.codeplex.com/wikipage?title=Attribute routing in Web API&amp;ANCHOR#C27291</link><description>It would be nice if the routes could also be defined on interfaces too.&amp;#10;&amp;#10;The use case for this is having an interface that defines the API and client classes &amp;#47; server classes that implement the interface.</description><author>corinblaikie</author><pubDate>Wed, 24 Apr 2013 11:16:44 GMT</pubDate><guid isPermaLink="false">New Comment on "Attribute routing in Web API" 20130424111644A</guid></item><item><title>New Comment on "CORS support for ASP.NET Web API"</title><link>https://aspnetwebstack.codeplex.com/wikipage?title=CORS support for ASP.NET Web API&amp;ANCHOR#C27252</link><description>Is this available for self-hosted&amp;#63;</description><author>mocsharp</author><pubDate>Sat, 20 Apr 2013 18:29:19 GMT</pubDate><guid isPermaLink="false">New Comment on "CORS support for ASP.NET Web API" 20130420062919P</guid></item></channel></rss>