基于M-M关系的OData过滤器
是否可以通过M-M关系中的链接实体在odata中进行过滤,其中必须包含所有第二个实体,但允许附加实体 假设我有: 学生 学生班 等级 我想找到所有学生,他们的注册包括课程(101、102、103)是的,OData v4提供了2个对集合中的布尔表达式求值的函数。它们是基于M-M关系的OData过滤器,odata,odata-v4,Odata,Odata V4,是否可以通过M-M关系中的链接实体在odata中进行过滤,其中必须包含所有第二个实体,但允许附加实体 假设我有: 学生 学生班 等级 我想找到所有学生,他们的注册包括课程(101、102、103)是的,OData v4提供了2个对集合中的布尔表达式求值的函数。它们是Any和All,其中Any如果至少有一个子条目符合条件,则返回记录,All要求所有子记录都匹配 在您的情况下,我们可以使用任何: 5.1.1.10.1任何 any运算符将布尔表达式应用于集合的每个成员,如果表达式对于集合的任何成员为t
Any
和All
,其中Any
如果至少有一个子条目符合条件,则返回记录,All
要求所有子记录都匹配
在您的情况下,我们可以使用任何:
5.1.1.10.1任何
any
运算符将布尔表达式应用于集合的每个成员,如果表达式对于集合的任何成员为true,则返回true,否则返回false。如果集合不是空的,则不带参数的any
运算符返回true
示例79:包含数量大于100的任何项目的所有订单
http://host/service/Orders?$filter=项目/任何(d:d/数量gt 100)
但是,我们无法通过数组或值列表进行比较,因此我们必须将此查询分解为每个值的Any
表达式以及和表达式。
这听起来有悖常理,但以下简单的查询(我们在单个Any
中使用或)会导致匹配,其中学生有一个或多个类(101102103),但不一定是所有类:
如果他们必须至少在所有101102103中注册,那么我们必须和每个类的一个单独的任何操作符的结果,下面是每个类的3个单独查询,以及一个将和组合在一起的最终查询:
http://host/service/Students?$filter=Enrollments/Any(e:e/Class/Code eq '101')
http://host/service/Students?$filter=Enrollments/Any(e:e/Class/Code eq '102')
http://host/service/Students?$filter=Enrollments/Any(e:e/Class/Code eq '103')
http://host/service/Students?$filter=Enrollments/Any(e:e/Class/Code eq '101') AND Enrollments/Any(e:e/Class/Code eq '102') AND Enrollments/Any(e:e/Class/Code eq '103')
这些查询假定:
Student
记录上有一个名为Enrollments
的导航属性,它将Student
链接到StudentClass
记录的集合,
StudentClass
有一个名为“Class”的导航属性,该属性将其链接到单个Class
记录,
类代码(101、102、103)存储在名为code
注意:不同的提供程序在不同程度上支持这些Lambda运算符,如果您有复杂的需求,如支持使用Any
或All
嵌套表达式,或者如果最简单的查询没有如您所期望的那样解决,则应与您的供应商/开发人员联系
此查询并不特别要求在结果中包含注册
或类
记录,它只应返回学生
的列表,除非默认情况下有服务器端配置或逻辑来扩展这些导航属性
虽然OP不需要,但如果您正在扩展这些相同的对象图(筛选依据),请务必指出,在根$filter
查询选项中使用Any
运算符将不会对扩展的子集合应用筛选。如果只想返回与表达式匹配的子记录,除了根$filter
查询选项中的Any
操作符外,还需要在$expand
查询选项中实现$filter
表达式
反之亦然,仅在$expand
查询选项中使用$filter
不会阻止顶级学生返回,如果他们只注册了其他课程,则不会返回任何课程,因为他们不符合条件,但它仍然会返回学生
记录
因此,当使用嵌套在$expand
中的$filter
时,在$filter
查询选项中包含Any
或All
操作符是很常见的。您应该包括URL或调用语法,以吸引您能够轻松使用的答案。利用这些信息,我们能做的最好的事情就是假设URL路由您的API使用,并提供理论上的响应。非常感谢您的详细解释,Chris。我在网上搜索了很长时间,以证明你表达得非常好的想法。关于将多个any/
子句与和
组合(如果需要将实体集合与值数组匹配)。OData v4的文档对于此类示例来说是缺乏的。在针对OData服务编写前端几年之后,现在@eugenezakarov,我发现自己越来越少地使用这些操作符。很好,OData具有这种灵活性,我的前端人员可以根据有效的开放API快速原型化,但大多数面向生产的代码都优化为自定义操作和函数。因此,虽然文档有点缺乏,但我觉得这是因为社区缺乏填补空白的需求和领导力。继续在SO中发布查询请求,我们会为您找到答案!我应该更新这篇文章,OData现在对IN操作符有了广泛的支持,这进一步简化了这种比较
http://host/service/Students?$filter=Enrollments/Any(e:e/Class/Code eq '101')
http://host/service/Students?$filter=Enrollments/Any(e:e/Class/Code eq '102')
http://host/service/Students?$filter=Enrollments/Any(e:e/Class/Code eq '103')
http://host/service/Students?$filter=Enrollments/Any(e:e/Class/Code eq '101') AND Enrollments/Any(e:e/Class/Code eq '102') AND Enrollments/Any(e:e/Class/Code eq '103')