OData $filter 与 $expand 中的项目

Posted

技术标签:

【中文标题】OData $filter 与 $expand 中的项目【英文标题】:OData $filter with items in a $expand 【发布时间】:2012-02-28 14:08:09 【问题描述】:

我已经提供了一些网络服务来访问信息。

我尝试扩展节点的第一件事。我已经用下面的代码成功地做到了

http://www.domain.com/ODataService/WorkService.svc/CaseStudies?format=json&$expand=ServiceOfferings

现在我想过滤我在扩展 ServiceOfferings 时将获得的 ServiceOfferingID。 如何对扩展集合使用过滤器选项

http://www.domain.com/ODataService/WorkService.svc/CaseStudies?format=json&$expand=ServiceOfferings&$filter=ServiceOfferings.ServiceOfferingID eq 127 

但它不起作用。做同样事情的正确方法是什么

【问题讨论】:

简短回答:将点更改为斜线,即&$filter=ServiceOfferings/ServiceOfferingID eq 127 应该可以工作。 【参考方案1】:

您需要编写的查询取决于扩展集合的cardinality。

以下是一些使用公共sample OData Northwind service, provided by odata.org 的示例。

一个订单总是由一个客户完成。

查找具有特定名称的客户所下的订单: http://services.odata.org/V3/Northwind/Northwind.svc/Orders?$expand=Customer&$filter=Customer/CompanyName eq 'Vins et alcools Chevalier'。这相当于Dhawal的回答。

一个客户可以发出许多订单。

使用quantifiers allany 来指定您是否希望至少一个或所有命令服从您的条件。

    查找一个或多个订单已由特定员工处理的客户: http://services.odata.org/V3/Northwind/Northwind.svc/Customers?$expand=Orders&$filter=Orders/any(o: o/EmployeeID eq 9) 查找很久没有订购任何东西的客户: http://services.odata.org/V3/Northwind/Northwind.svc/Customers?$expand=Orders&$filter=Orders/all(o: o/OrderDate lt DateTime'1997-01-01')

您可以调用http://services.odata.org/V3/Northwind/Northwind.svc/$metadata 并检查 NavigationProperty 元素,以查看存在哪些关系。

<NavigationProperty Name="Orders" 
    Relationship="NorthwindModel.FK_Orders_Customers" 
    ToRole="Orders" 
    FromRole="Customers"/>

然后,查找与该名称的关联,您将找到基数:

<Association Name="FK_Orders_Customers">
    <End 
         Type="NorthwindModel.Customer" 
         Role="Customers" 
         Multiplicity="0..1"/>
    <End 
         Type="NorthwindModel.Order" 
         Role="Orders" 
         Multiplicity="*"/>
    ...

像这样导航一对多关系:http://services.odata.org/V3/Northwind/Northwind.svc/Customers?$expand=Orders&$filter=Orders/EmployeeID eq 9,会给你:“属性“EmployeeID”的属性访问的父值不是单个值。属性访问只能是应用于单个值。”

导航与 all 或 any 的多对一关系,例如http://services.odata.org/V3/Northwind/Northwind.svc/Orders?$expand=Customer&$filter=Customer/any(c: c/CompanyName eq 'Vins et alcools Chevalier'),将为您提供: “Any/All 只能在集合之后使用。”

顺便说一下,all()any() 实际上分别是 Universal quantifier, ∀() 和 existential quantifier, ∃(),你可能记得在数学课上。

【讨论】:

你熟悉Simple.OData.Client吗?我很好奇它是否支持过滤扩展。【参考方案2】:

oData 支持按子对象的属性过滤。

这是一个例子: http://services.odata.org/Northwind/Northwind.svc/Orders?$filter=Customer/Country eq 'Germany'

【讨论】:

您知道Simple.OData.Client 是否可以实现这一目标?【参考方案3】:

在 OData 中,过滤器命令仅适用于***元素。要使您的过滤器正常工作,您需要具有以下 URL

http://www.example.com/ODataService/WorkService.svc/CaseStudies(x)/ServiceOfferings?format=json&amp;$filter=ServiceOfferingID eq 127

显然这不是您要编写的查询,但在幕后您的查询被转换为具有基于***元素的根表达式的表达式树。

如果您确实需要过滤数据,您可能会拦截查询并编写自己的表达式,如下所示:

[QueryInterceptor("CaseStudies")]
public Expression<Func<CaseStudie, bool>> CaseStudieFilter()

    <Expression here>

【讨论】:

@nil 如果您阅读了他们实际上在谈论在扩展上进行过滤的问题,这是我的回答所针对的,这与在复杂类型上进行过滤不同,因此尽管您可能会说这不是真的这是为了扩展【参考方案4】:

可能对某人有帮助

GET serviceRoot/People?$expand=Trips($filter=Name eq 'Trip in US')

【讨论】:

@Muhammad_Tayyab 你知道如何格式化 url 以仅返回扩展数据集不为空的结果吗?例如,Trips 可能等于“Trips”:[]【参考方案5】:

您也可以通过服务上的 webget 来完成此操作。我不得不做一些类似于按属性过滤的事情。

【讨论】:

以上是关于OData $filter 与 $expand 中的项目的主要内容,如果未能解决你的问题,请参考以下文章

将 ODATA $expand 查询选项与 WebAPI 和 ViewModel 一起使用

带有 odata 和 $expand 的 Web Api 2.2

Sapui5:如果有oData参数,如何将oData服务绑定到SAPUI5表

odata - 结合 $expand 和 $select

使用 $expand 时的 Web API OData 媒体类型格式化程序

OData $expand、DTO 和实体框架