How to select only OData child elements

社会主义新天地 提交于 2019-12-11 03:53:18

问题


I'm building an OData application and I'm struggling on how to retrieve results and only include certain (child properties).

First, let me show you the registration in my builder:

builder.EntitySet<AggregatedArticlesSearchModel>("Search").EntityType.HasKey(x => x.Name);

Now, on to the model that I'm returning from my Query:

<EntityType Name="AggregatedArticlesSearchModel">
    <Key>
        <PropertyRef Name="Name"/>
    </Key>
    <Property Name="Name" Nullable="false" Type="Edm.String"/>
    <Property Name="Values" Type="Collection(Zevij_Necomij.Mobile.App.Api.Models.OccurenceViewModel)"/>
</EntityType>
<ComplexType Name="OccurenceViewModel">
    <Property Name="Value" Type="Edm.String"/>
    <Property Name="Count" Nullable="false" Type="Edm.Double"/>
    <Property Name="Articles" Type="Collection(Zevij_Necomij.Mobile.App.Api.Models.AggregatedArticleDescriptionViewModel)"/>
</ComplexType>
<ComplexType Name="AggregatedArticleDescriptionViewModel">
    <Property Name="Name" Type="Edm.String"/>
    <Property Name="Specification" Type="Edm.String"/>
    <Property Name="Brand" Type="Edm.String"/>
</ComplexType>

When I'm executing a request to get the data, I'm not doing anything fancy but just returning the results from the database:

public async Task<IHttpActionResult> Get()
{
    // Create all the managers for the platform context that are required by the application.
    var classificationManager = Context.CreateManager(typeof(AggregatedArticleManager<>)) as AggregatedArticleManager<IAggregatedArticleStore<AggregatedArticle>>;

    var classifications = await classificationManager.GetAllAsync();

    var returnList = classifications.OrderBy(x => x.Name).Select(AggregatedArticlesSearchModel.MapFromDbModel).ToList();

    return Ok(returnList.AsQueryable());
}

Since I'm working with child objects, the list can get quite huge:

{
  "@odata.context":     "http://api.mobileapp.appserver.dev.dsoft.be/OData/$metadata#Search",
  "value": [
    {
      "Name": "(Veiligheids)slipkoppeling",
      "Values": [
        {
          "Value": "ja",
          "Count": 118,
      "Articles": [
        {
          "Name": "230 V Sleuvenzaag",
          "Specification": "Compacte machine",
          "Brand": "Makita"
        },
        {
          "Name": "230V Cirkelzaag SJS",
          "Specification": "Softstart voor
        },
    }
}

I can have a thousand articles in a single set, thus, way to much to return over the Web Api. Since I don't need all those properties in a single request, I was thinking to let the cliënt only retrieve child properties by using the ?$select parameter, thus the cliënts can say for example:

OData/Search?$select=Values

The problem here is that I for example, only want to return the Count, thus, I tought that a request like this was possible:

OData/Search?$select=Values/Count

However, this leads to an OData error: "The query specified in the URI is not valid. Found a path with multiple navigation properties or a bad complex property path in a select clause. Please reword your query such that each level of select or expand only contains either TypeSegments or Properties."

Anyone who has an idea on how to solve this one?


回答1:


@Complexity

As I know, to select a sub property in a property is not supported.

However, if you build the OccurenceViewModel as entity type, then you can use the nested $select in $expand to meet your requirement.

For example:

1) build the entity type

builder.EntitySet<OccurenceViewModel>("ViewModels").EntityType.HasKey(x => x.Value);

then, Values in AggregatedArticlesSearchModel should be a navigation property.

2) Now, you can issue a GET request as follows to only return the Count property:

GET ~/odata/Search?$select=Values&$expand=Values($select=Count)

Then, the payload should look like the below:

{
  "@odata.context":"http://localhost/odata/$metadata#Search(Values,Values(Count))","value":[
    {
      "Values":[
        {
          "Count":101.0
        },{
          "Count":102.0
        }
      ]
    },{
      "Values":[
        {
          "Count":101.0
        },{
          "Count":102.0
        }
      ]
    }
  ]
}

Hope it can help you. Thanks.



来源:https://stackoverflow.com/questions/32690408/how-to-select-only-odata-child-elements

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!