OData 按 M-M 关系过滤
OData Filter by an M-M relationship
是否可以通过 M-M 关系中的链接实体过滤 odata,其中它必须包含所有第二个,但允许额外的?
假设我有:
学生
学生Class
Class
我想找到所有学生,他们的入学人数包括 类 (101, 102, 103)
是的,OData v4 提供了 2 Lambda Operators 来计算集合上的布尔表达式。这些是 Any
和 All
,其中 Any
return 如果 至少一个 子条目符合条件,则为记录,并且All
需要 所有 个子记录匹配。
在你的情况下,我们可以使用 Any
:
5.1.1.10.1 any
The any
operator applies a Boolean expression to each member of a collection and returns true if the expression is true for any member of the collection, otherwise it returns false. The any
operator without an argument returns true if the collection is not empty.
Example 79: all Orders that have any Items with a Quantity greater than 100
http://host/service/Orders?$filter=Items/any(d:d/Quantity gt 100)
但是我们无法通过数组或值列表进行比较,因此我们必须将此查询分解为每个值的 Any
表达式并将它们 AND
在一起。
这听起来违反直觉,但下面的简单查询我们在 单个 Any
中使用 OR
会导致 Student 具有 一个或多个的匹配项class 中的 (101,102,103) 但不一定是 所有 个:
http://host/service/Students?$filter=Enrollments/Any(e:e/Class/Code eq '101' or e/Class/Code eq '102' or e/Class/Code eq '103')
如果他们必须参加 atleast all of 101,102,103 那么我们必须 AND
一个单独的 [=每个 classes 的 12=] 运算符,下面是每个 class 的 3 个单独查询和 AND
将它们放在一起的最终查询:
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')
这些查询假定:
在名为 Enrollments
的 Student
记录上有一个导航 属性,它将 Student
链接到 StudentClass
的集合 记录,
StudentClass
有一个名为 'Class' 的导航 属性,将其链接到 单个 Class
记录,
class 代码 (101,102,103) 存储在 string 属性 在 Class
记录上调用 Code
NOTE: Different providers support these Lambda operators to different extents, you should check with your vendor/developer if you have have complex needs like support for nesting expressions with Any
or All
or if the simplest queries are not resolving as you expect.
这个查询没有特别要求 Enrollments
或 Class
记录包含在结果中,它应该只是 return Students
的列表,除非有默认情况下,$expand
这些导航属性是服务器端配置或逻辑。
虽然 OP 不需要,但如果您正在扩展这些相同的对象图(您正在过滤),重要的是要指出在根 $filter
中使用 Any
运算符查询选项不会对展开的子集合应用过滤。如果您想要 return ONLY 与表达式匹配的子记录,您需要在 $expand
查询选项中实现 $filter
表达式,除了根$filter
查询选项中的Any
运算符。
反之亦然,仅在 $expand
查询选项中使用 $filter
不会阻止顶级 Student
被 return 编辑,如果它们是只注册了其他 classes,它不会 return 任何 classes 因为它们不符合条件,但它仍然会 return Student
记录。
因此,当使用 $filter
嵌套在 $expand
中时,很常见 包含 Any
或 All
运算符在 $filter
查询选项中。
是否可以通过 M-M 关系中的链接实体过滤 odata,其中它必须包含所有第二个,但允许额外的?
假设我有: 学生 学生Class Class 我想找到所有学生,他们的入学人数包括 类 (101, 102, 103)
是的,OData v4 提供了 2 Lambda Operators 来计算集合上的布尔表达式。这些是 Any
和 All
,其中 Any
return 如果 至少一个 子条目符合条件,则为记录,并且All
需要 所有 个子记录匹配。
在你的情况下,我们可以使用 Any
:
5.1.1.10.1 any
Theany
operator applies a Boolean expression to each member of a collection and returns true if the expression is true for any member of the collection, otherwise it returns false. Theany
operator without an argument returns true if the collection is not empty.Example 79: all Orders that have any Items with a Quantity greater than 100
http://host/service/Orders?$filter=Items/any(d:d/Quantity gt 100)
但是我们无法通过数组或值列表进行比较,因此我们必须将此查询分解为每个值的 Any
表达式并将它们 AND
在一起。
这听起来违反直觉,但下面的简单查询我们在 单个 Any
中使用 OR
会导致 Student 具有 一个或多个的匹配项class 中的 (101,102,103) 但不一定是 所有 个:
http://host/service/Students?$filter=Enrollments/Any(e:e/Class/Code eq '101' or e/Class/Code eq '102' or e/Class/Code eq '103')
如果他们必须参加 atleast all of 101,102,103 那么我们必须 AND
一个单独的 [=每个 classes 的 12=] 运算符,下面是每个 class 的 3 个单独查询和 AND
将它们放在一起的最终查询:
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')
这些查询假定:
在名为 Enrollments
的 Student
记录上有一个导航 属性,它将 Student
链接到 StudentClass
的集合 记录,
StudentClass
有一个名为 'Class' 的导航 属性,将其链接到 单个 Class
记录,
class 代码 (101,102,103) 存储在 string 属性 在 Class
记录上调用 Code
NOTE: Different providers support these Lambda operators to different extents, you should check with your vendor/developer if you have have complex needs like support for nesting expressions with
Any
orAll
or if the simplest queries are not resolving as you expect.
这个查询没有特别要求 Enrollments
或 Class
记录包含在结果中,它应该只是 return Students
的列表,除非有默认情况下,$expand
这些导航属性是服务器端配置或逻辑。
虽然 OP 不需要,但如果您正在扩展这些相同的对象图(您正在过滤),重要的是要指出在根 $filter
中使用 Any
运算符查询选项不会对展开的子集合应用过滤。如果您想要 return ONLY 与表达式匹配的子记录,您需要在 $expand
查询选项中实现 $filter
表达式,除了根$filter
查询选项中的Any
运算符。
反之亦然,仅在 $expand
查询选项中使用 $filter
不会阻止顶级 Student
被 return 编辑,如果它们是只注册了其他 classes,它不会 return 任何 classes 因为它们不符合条件,但它仍然会 return Student
记录。
因此,当使用 $filter
嵌套在 $expand
中时,很常见 包含 Any
或 All
运算符在 $filter
查询选项中。