如何只选择OData子元素

时间:2015-09-21 08:18:24

标签: c# odata

我正在构建一个OData应用程序,我正在努力研究如何检索结果,并且只包含某些(子属性)。

首先,让我向您展示我的构建器中的注册:

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

现在,关于我从查询中返回的模型:

<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>

当我执行获取数据的请求时,我没有做任何花哨的事情,只是从数据库中返回结果:

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

由于我正在使用子对象,因此列表可能非常庞大:

{
  "@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
        },
    }
}

我可以在一个集合中拥有一千篇文章,因此,通过Web Api返回的方式很多。 由于我不需要在单个请求中使用所有这些属性,因此我想让cliënt仅使用?$select参数检索子属性,因此cliënts可以说例如:

OData/Search?$select=Values

这里的问题是我,例如,我只想返回Count,因此,我认为这样的请求是可能的:

OData/Search?$select=Values/Count

但是,这会导致OData错误:"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."

有任何想法如何解决这个问题的人?

1 个答案:

答案 0 :(得分:4)

@Complexity

据我所知,不支持在属性中选择子属性。

但是,如果您将OccurenceViewModel构建为实体类型,则可以使用$ expand中的嵌套$ select来满足您的要求。

例如:

1)构建实体类型

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

然后,Values中的AggregatedArticlesSearchModel应该是导航属性。

2)现在,您可以按如下方式发出GET请求,只返回Count属性:

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

然后,有效载荷应如下所示:

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

希望它可以帮到你。感谢。