1 対多の関係を持つ関連コレクションのフィルターを使用してコレクションから選択する OData 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 /従業員ID
これは与える:
{"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 によって処理されたすべての注文 (この場合は 1 つだけ) が含まれています。2 番目と 3 番目のアイテムについては、結果セットに注文アイテムはありません。さらに調べてみると、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' のフィルター述語は未定であり、3 値論理の規則に従って、'FISSA' と 'PARIS' は結果セットに含まれるべきではないと思います。したがって、これはこの OData 実装のバグだと思います。
注文のない顧客を除外するための正しい OData 要求クエリを知っている人はいますか?