title: Web API OData Typeless support for $select query option
body: <p>I am working with the new typeless support in ASP.NET Web API 2 OData. I am interested in providing support for the <strong>$select</strong> query option. How do I omit the structural properties from the EdmEntityObject that were not selected by the $select query option?</p>
  
  <p>The following is a sample of the Web API Configuration for a very simple example working with a typeless model. </p>
  
  <pre><code>public static IEdmModel BuildEdmModel()
  {
      var model = new EdmModel();
      var container = new EdmEntityContainer("Model", "OData");
      var product = new EdmEntityType("Model", "Product");
      var productKey = product.AddStructuralProperty("ID", EdmPrimitiveTypeKind.Guid);
      product.AddKeys(productKey);
      product.AddStructuralProperty("Name", EdmPrimitiveTypeKind.String);
      product.AddStructuralProperty("Price", EdmPrimitiveTypeKind.Double);
      model.AddElement(product);
      model.AddElement(container);
      model.SetIsDefaultEntityContainer(container, true);
      container.AddEntitySet("Products", product);
  
      return model;
  }
  
  public static void Register(HttpConfiguration config)
  {
      config.Routes.MapODataRoute("ODataRoute", "odata", BuildEdmModel());
  }
  </code></pre>
  
  <p>The following is a partial snippet from a simple ODataController</p>
  
  <pre><code>public EdmEntityObjectCollection Get()
  {
      var path = Request.GetODataPath();
      var edmType = path.EdmType;
      var collectionType = edmType as IEdmCollectionType;
      var entityType = collectionType.ElementType.AsEntity();
      var entitySetName = entityType.EntityDefinition().Name;
      var model = Request.GetEdmModel();
      var queryContext = new ODataQueryContext(Request.GetEdmModel(), entityType.Definition);
      var queryOptions = new ODataQueryOptions(queryContext, Request);
  
      return GetData(Request.GetEdmModel(), queryOptions);
  }
  
  public static EdmEntityObjectCollection GetData(IEdmModel edmModel, ODataQueryOptions queryOptions)
  {
      var selectedPropertyNames = new string[0];
      // determine the selected property names
      if (queryOptions.SelectExpand != null &amp;&amp; queryOptions.SelectExpand.SelectExpandClause != null &amp;&amp; (!queryOptions.SelectExpand.SelectExpandClause.AllSelected || queryOptions.SelectExpand.SelectExpandClause.SelectedItems.OfType&lt;WildcardSelectItem&gt;().Any()))
      {
          selectedPropertyNames = queryOptions.SelectExpand.RawSelect.Split(',');
      }    
  
      // TODO: Now that we have the selected properties, how do I remove the structural properties from the EdmEntityObject that were not selected by the $select query option?
  
      var productSchemaType = edmModel.FindDeclaredType(string.Format("{0}.Product", "Model"));
      var productEntityType = productSchemaType as IEdmEntityType;
      var productEntityTypeReference = new EdmEntityTypeReference(productEntityType, true);
      var products = new EdmEntityObjectCollection(new EdmCollectionTypeReference(new EdmCollectionType(productEntityTypeReference), true));
  
      var productWindows = new EdmEntityObject(productEntityTypeReference);
      productWindows.TrySetPropertyValue("ID", new Guid("52D811A0-9065-4B83-A2E8-0248FBA9FBF5"));
      productWindows.TrySetPropertyValue("Name", "Microsoft Windows 8");
      productWindows.TrySetPropertyValue("Price", 179.99);
  
      var productOffice = new EdmEntityObject(productEntityTypeReference);
      productOffice.TrySetPropertyValue("ID", new Guid("CB39EBD0-4751-4D5F-A76C-78FCC7A9CE1A"));
      productOffice.TrySetPropertyValue("Name", "Microsoft Office 2013");
      productOffice.TrySetPropertyValue("Price", 399.99);
  
      products.Add(productWindows);
      products.Add(productOffice);
  
      return products;
  }
  </code></pre>
  
  <p>This will output:</p>
  
  <pre><code>{
    "odata.metadata":"http://localhost:59511/odata/$metadata#Products","value":[
      {
          "ID":"52d811a0-9065-4b83-a2e8-0248fba9fbf5","Name":"Microsoft Windows 8","Price":179.99
      },{
          "ID":"cb39ebd0-4751-4d5f-a76c-78fcc7a9ce1a","Name":"Microsoft   Office 2013","Price":399.99
      }
    ]
  }
  </code></pre>
  
  <p>If the user applies a $select query option, for example <strong>/odata/Products?$select=Name</strong>. This should result in the following output:</p>
  
  <pre><code>{
    "odata.metadata":"http://localhost:59511/odata/$metadata#Products","value":[
      {
        "Name":"Microsoft Windows 8"
      },{
        "Name":"Microsoft Office 2013"
      }
    ]
  }
  </code></pre>
  
  <p>Any help would be greatly appreciated</p>