按嵌套集合过滤计数排序

Order by nested collection filtered count

我正在尝试按嵌套集合过滤计数进行排序,但不知道如何在 OData 中执行此操作。

我会用public OData API (from Microsoft) demo来说明我的意思,不需要授权

https://services.odata.org/TripPinRESTierService/

所以我们有 People

https://services.odata.org/TripPinRESTierService/People

这些PeopleTrips

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 版本,它可能也会正常工作。

更新 这仅支持 Microsoft.OData.Core 版本 >= 7.9.4 基于 this pr.


您应该能够在您的 $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"
            }
        ]
    }
  ]
}