如何通过子字段过滤OData查询,移除无数据的父节点?
问题
尝试使用OData v4.0的$expand在多层实体中结合过滤获取嵌套JSON结构,当前查询语句如下:
https://{{context-path}}/Workers?$select=WorkerId,WorkerNumber&$expand=AbsenceHeaders($select=AbsenceHeaderId,WorkerId;$expand=AbsenceDailyDetails($select=Date,AbsenceHeaderId,IsAbsentDay;$filter=IsAbsentDay eq true and (Date ge 2022-06-07 and Date le 2022-06-10)))&$filter=WorkerId eq 201&$format=application/json;odata.metadata=none
该查询返回结果包含AbsenceDailyDetails为空数组的AbsenceHeader节点:
{ "value": [ { "WorkerId": 201, "WorkerNumber": "08063", "AbsenceHeaders": [ { "WorkerId": 201, "AbsenceHeaderId": 151252, "AbsenceDailyDetails": [] }, { "WorkerId": 201, "AbsenceHeaderId": 156585, "AbsenceDailyDetails": [ { "Date": "2022-06-07", "AbsenceHeaderId": 156585, "IsAbsentDay": true, "AbsenceDailyDetailId": 1025375698 } ] } ] } ] }
期望过滤掉所有AbsenceDailyDetails为空的AbsenceHeader节点,仅保留含有效数据的节点:
{ "value":[ { "WorkerId":201, "WorkerNumber":"08063", "AbsenceHeaders":[ { "WorkerId":201, "AbsenceHeaderId":156585, "AbsenceDailyDetails":[ { "Date":"2022-06-07", "AbsenceHeaderId":156585, "IsAbsentDay":true, "AbsenceDailyDetailId":1025375698 } ] } ] } ] }
尝试在$expand中添加额外过滤条件时收到URI格式错误:
$expand=AbsenceHeaders($filter=AbsenceDailyDetails/IsAbsentDay eq true and (AbsenceDailyDetails/Date ge 2022-06-07 and AbsenceDailyDetails/Date le 2022-06-10))
解决方案
要实现过滤掉无有效AbsenceDailyDetails的AbsenceHeader节点,需要在AbsenceHeaders的$filter中使用存在性判断,同时结合子实体的过滤条件,正确的查询语句如下:
https://{{context-path}}/Workers?$select=WorkerId,WorkerNumber&$expand=AbsenceHeaders($select=AbsenceHeaderId,WorkerId;$expand=AbsenceDailyDetails($select=Date,AbsenceHeaderId,IsAbsentDay;$filter=IsAbsentDay eq true and Date ge 2022-06-07 and Date le 2022-06-10);$filter=exists(AbsenceDailyDetails/IsAbsentDay eq true and AbsenceDailyDetails/Date ge 2022-06-07 and AbsenceDailyDetails/Date le 2022-06-10))&$filter=WorkerId eq 201&$format=application/json;odata.metadata=none
关键说明:
- 使用
exists()函数判断AbsenceHeader是否存在符合条件的AbsenceDailyDetails子实体,这是OData v4.0中过滤关联实体存在性的标准写法。 - 原尝试的写法直接引用子实体属性未包装在
exists()中,不符合OData的语法规范,因此会报URI格式错误。 - 同时保留
AbsenceDailyDetails层级的$filter,确保只返回符合日期和状态条件的明细数据,再通过AbsenceHeaders的$filter过滤掉没有有效明细的父节点。
内容的提问来源于stack exchange,提问作者VoiceOfReason
相关产品推荐
相关产品推荐

