按嵌套集合过滤计数排序
Posted
技术标签:
【中文标题】按嵌套集合过滤计数排序【英文标题】:Order by nested collection filtered count 【发布时间】:2022-01-10 17:25:46 【问题描述】:我正在尝试,但不知道如何在 OData 中执行此操作。
我将使用公共 OData API(来自 Microsoft)进行演示来解释我的意思,无需授权
https://services.odata.org/TripPinRESTierService/
所以我们在那里有People
https://services.odata.org/TripPinRESTierService/People
这些People
有Trips
https://services.odata.org/TripPinRESTierService/People?$expand=Trips
如果我想通过Name
过滤Trips
,这很容易
https://services.odata.org/TripPinRESTierService/People?$expand=Trips($filter=Name eq 'Trip in Beijing')
如果我想按Trip
计数订购People
,也很简单
https://services.odata.org/TripPinRESTierService/People?$expand=Trips($count=true)&$orderby=Trips/$count desc
但我无法通过过滤的行程次数进行排序(例如$expand=Trips($filter=Name eq 'Trip in Beijing')
)
https://services.odata.org/TripPinRESTierService/People?$expand=Trips($count=true;$filter=Name eq 'Trip in Beijing')&$orderby=Trips/$count desc
&$orderby=Trips($filter=Name eq 'Trip in Beijing')/$count desc
或 &$orderby=Trips/$count($filter=Name eq 'Trip in Beijing') desc
之类的东西不起作用(导致服务器错误 "Could not find a property named 'Name' on type 'Trippin.Person'."
)。
此 URL 的版本以查看所需的最少数据
https://services.odata.org/TripPinRESTierService/People?$expand=Trips($top=0;$count=true;$filter=Name eq 'Trip in Beijing')&$orderby=Trips/$count desc&$select=Trips
更新:我在我的项目中使用Microsoft.AspNetCore.OData
7.5.7 版本,它依赖于Microsoft.OData.Core
7.7.3 版本(未明确安装)。如果微软将在其 API 中升级 OData 版本,它可能也会正常工作。
【问题讨论】:
您好,请问您在查询时能提供从服务器得到的错误信息吗? @Max 哪一个?请注意,您可以在浏览器或 Postman 中运行所有列出的查询并进行试验。 【参考方案1】:更新这仅支持基于 this pr 的 Microsoft.OData.Core 版本 >= 7.9.4。
您应该能够在您的 $orderby 中重复与您在 $expand 中相同的过滤条件,以获得您正在寻找的内容。
/odata/People?$expand=Trips($count=true;$filter=Name eq 'Paris')&$orderby=Trips/$count($filter=Name eq 'Paris') desc
"@odata.context": "https://localhost:5001/odata/$metadata#People(Trips())",
"value": [
"Id": "d31713ca-236b-470f-bb9e-f5bd6fac3d8e",
"Name": "Aaron",
"Trips@odata.count": 2,
"Trips": [
"Id": "741656bf-f5e6-4f18-855f-ca1b3c0eb478",
"Name": "Paris"
,
"Id": "741656bf-f5e6-4f18-855f-ca1b3c0eb478",
"Name": "Paris"
]
,
"Id": "34c0ac10-1c0d-4a29-89ad-386a3fea893b",
"Name": "Bob",
"Trips@odata.count": 1,
"Trips": [
"Id": "1b35a96d-ca98-438a-b63c-1478ae0661cb",
"Name": "Paris"
]
,
"Id": "192dd197-6f25-4842-bb9f-207b5df221c2",
"Name": "Jeff",
"Trips@odata.count": 0,
"Trips": []
]
为了比较,这里是没有 $filter 的相同数据集。
/odata/People?$expand=Trips($count=true)&$orderby=Trips/$count desc
"@odata.context": "https://localhost:5001/odata/$metadata#People(Trips())",
"value": [
"Id": "192dd197-6f25-4842-bb9f-207b5df221c2",
"Name": "Jeff",
"Trips@odata.count": 3,
"Trips": [
"Id": "4537521c-27a6-4fa4-8bb5-fd94937abd56",
"Name": "Cleveland"
,
"Id": "40431cba-0d8f-470a-9647-bdd99009737a",
"Name": "Cleveland"
,
"Id": "1269c3e3-b5ff-4a73-8201-5388d00ea744",
"Name": "Cleveland"
]
,
"Id": "d31713ca-236b-470f-bb9e-f5bd6fac3d8e",
"Name": "Aaron",
"Trips@odata.count": 2,
"Trips": [
"Id": "741656bf-f5e6-4f18-855f-ca1b3c0eb478",
"Name": "Paris"
,
"Id": "741656bf-f5e6-4f18-855f-ca1b3c0eb478",
"Name": "Paris"
]
,
"Id": "34c0ac10-1c0d-4a29-89ad-386a3fea893b",
"Name": "Bob",
"Trips@odata.count": 1,
"Trips": [
"Id": "1b35a96d-ca98-438a-b63c-1478ae0661cb",
"Name": "Paris"
]
]
【讨论】:
我明白了。在您的示例中对 api 进行相同的尝试会给我相同的结果。在您的最终实施中,您是否使用特定版本的 OData?我能够使用 OData 8.0.4 使用本地 .NET 5 Web API 可靠地重现我的答案中的行为。我很乐意分享我的源代码。 我发现了这个 pr,这让我觉得这可能只在更新的版本中得到支持。 github.com/OData/odata.net/pull/2051/files 如果你想进一步深入了解,这里是我的仓库github.com/tyharbert/ODataApiSandbox 太好了,我能够对其进行测试并设法升级我的代码。 NuGet 包Microsoft.AspNetCore.OData
8.0+ 版本有大量的重大变化,我什至可以说它完全重新设计了 API。所以我还没有计划升级它,因为它需要付出巨大的努力来升级。我可以通过将Microsoft.AspNetCore.OData
从版本 7.5.7 升级到目前最新的 7.x 版本 7.5.12 来修复它。这取决于包含此修复程序的 Microsoft.OData.Core
版本 7.9.0。
所以解决方案是选项 1:使用 7.5.12 版的Microsoft.AspNetCore.OData
(或更高版本,如果将发布),它将隐式使用Microsoft.OData.Core
7.9.0 版(或更高版本)或选项 2:显式安装 Microsoft.OData.Core
版本 7.9.0+。以上是关于按嵌套集合过滤计数排序的主要内容,如果未能解决你的问题,请参考以下文章