2013-11-26 103 views
1

我正在ASP.NET Web API 2 OData中使用新的無類型支持。我有興趣爲$ select查詢選項提供支持。如何省略未由$ select查詢選項選中的EdmEntityObject的結構屬性?

以下是Web API配置示例,它是一個使用無類型模型的非常簡單的示例。

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()); 
} 

下面是一個簡單的ODataController的局部片斷

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 && queryOptions.SelectExpand.SelectExpandClause != null && (!queryOptions.SelectExpand.SelectExpandClause.AllSelected || queryOptions.SelectExpand.SelectExpandClause.SelectedItems.OfType<WildcardSelectItem>().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; 
} 

這將輸出:

{ 
    "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 
    } 
    ] 
} 

如果用戶施加$ select查詢選項,例如/OData的/產品?$ select =名稱。這將導致下面的輸出:

{ 
    "odata.metadata":"http://localhost:59511/odata/$metadata#Products","value":[ 
    { 
     "Name":"Microsoft Windows 8" 
    },{ 
     "Name":"Microsoft Office 2013" 
    } 
    ] 
} 

任何幫助,將不勝感激

回答

-1

有兩種方法來解決你的問題,如果我理解正確你的問題。

  1. 呼叫ODataQueryOptions對IQueryable的結果ApplyTo方法
    return queryOptions.ApplyTo(products);

  2. 添加屬性可查詢的GetData方法,讓的WebAPI處理查詢選項
    [Queryable]
    public static EdmEntityObjectCollection GetData(IEdmModel edmModel) {...}

+0

這個答案不正確,因爲'ApplyTo'和'[EnableQuery]'只適用於CLR類型。 –

0

這是我的代碼。

private void ApplySelectExpand(SelectExpandQueryOption selectExpand) 
    { 
     if (selectExpand != null) 
     { 
      Request.SetSelectExpandClause(selectExpand.SelectExpandClause); 
     } 
    } 
1

以下對我有用。

var oDataProperties = Request.ODataProperties() 
oDataProperties.SelectExpandClause = queryOptions.SelectExpand.SelectExpandClause; 

擴展功能在System.web.OData.dll v5.2.0.0中。