返回与过滤器不匹配的项目的OData请求

时间:2014-01-24 09:51:48

标签: odata northwind three-valued-logic

我正在尝试编写一个OData URL,该URL将从具有一对多关系的相关集合上的过滤器的集合中进行选择。过滤器要求相关集合项都具有某些属性的特定值。

为了说明这个问题,我为Northwind示例OData服务编写了一个类似的URL。此查询应选择所有订单已由同一员工处理的所有客户。 http://services.odata.org/V3/Northwind/Northwind.svc/Customers?$expand=Orders&$filter=Orders/all(o: o/EmployeeID eq 4)&$select=CustomerID,Orders/OrderID,Orders/EmployeeID

这给出了:

{"odata.metadata":"http://services.odata.org/V3/Northwind/Northwind.svc/$metadata#Customers&$select=CustomerID,Orders/OrderID,Orders/EmployeeID","value":
[{"Orders":[{"OrderID":10259,"EmployeeID":4}],"CustomerID":"CENTC"}
,{"Orders":[],"CustomerID":"FISSA"}
,{"Orders":[],"CustomerID":"PARIS"}]}

第一项确实包括员工4处理的所有订单(在这种情况下,只有一项)。对于第二项和第三项,结果集中没有订单项。在进一步检查时,http://services.odata.org/V3/Northwind/Northwind.svc/Customers?$expand=Orders&$filter=(CustomerID eq 'FISSA')&$select=CustomerID,Orders/OrderID,Orders/EmployeeID显示'FISSA'确实没有任何命令(对于'PARIS'也是如此)。

也许有人可以推断,因为'FISSA'没有任何命令不遵守过滤谓词,谓词就成立了。实际上,这可能是在SQL中解析此查询的方式:

select c.CustomerID
from Customers c
where c.CustomerID not in (select CustomerID from Orders o where o.EmployeeID != 4)

返回相同的3个客户,但加入Orders表可以解决这个问题:

select c.CustomerID, o.OrderID, o.EmployeeID
from Customers c
join Orders o
on c.CustomerID = o.CustomerID
where c.CustomerID not in (select CustomerID from Orders o where o.EmployeeID != 4) 

只返回'CENTC'。

我认为过滤器谓词对于'FISSA'是未定的,并且遵循三值逻辑的规则,'FISSA'和'PARIS'不应该在结果集中。所以,我认为这是OData实现中的一个错误。

是否有人知道正确的OData请求查询以忽略没有订单的客户?

1 个答案:

答案 0 :(得分:0)

在$ filter中添加any可以删除任何空匹配:Orders / any(o:o / EmployeeID ne null)

  

http://services.odata.org/V3/Northwind/Northwind.svc/Customers $扩大=订单&安培; $选择=客户ID,订单/订单ID,订单/雇员&安培; $滤波器=订单/所有(O 2:   o / EmployeeID eq 4)和Orders / any(o:o / EmployeeID ne null)

相关问题