我有一个ODATA服务MyService,其中包含客户,产品和类别,其中导航属性是从客户定义到产品,从产品定义到类别。
我对从客户到产品到类别的导航的正确形式感到困惑。
最初我给了MyService / Customers(1)/ Products(10)/ Categories,但它给了我一个错误。
然后我尝试了MyService / Customers(1)/ Products / Categories,它们正常工作。我在互联网上看到了许多我最初尝试过的uri形式的例子,但它对我不起作用。
任何人都可以解释一下吗?
答案 0 :(得分:2)
URI的正确形式取决于导航属性Products的多样性。如果客户可以拥有多个产品,那么第一个表格是正确的。如果客户最多只能有一个产品,那么第二个表格是正确的。
也许在您的服务中,此导航属性的多重性设置不正确。
答案 1 :(得分:0)
使用括号指定资源键表示这是一个 OData v4 主题。
根据规范 OData v4: 4.3.3 URLs for Related Entities with Referential Constraints,只要 Porducts
是集合类型,您的语法就是合规的。
包括未来相关资源的相关 $metadata
以解决这种歧义。
如果您的第二种形式的 URL 有效,则通常表明 Products
导航属性的多重性是单一的,使其不再是一个集合,因此您无法按 键.在这种情况下,如上所述,您可以使用 $filter
查询选项,但您也可以直接查询 Categories
控制器。
即使语法符合要求并且资源导航到 Products
IS 是一个集合,但在许多实现中,这种类型的导航特性不受支持。也许是因为它是不必要的,但也可能是因为它在意图方面是一个灰色区域,因此代码框架默认情况下很难在该区域强制执行路由约定或规则。
例如,这个查询应该由 Customers
控制器评估,但返回 Category
资源的集合,还是应该由 Products
控制器评估以返回一个集合Category
资源?如果 Category
控制器是返回和查询 Category
资源的控制器,而不是潜在地向所有 Customer
添加相同的支持,那么设计底层控制器不是更容易吗? ,Product
和 Category
控制器?
鉴于 10
的唯一键已提供给预期的 Product
资源返回,Customer
键 1
无关紧要。
如果您想故意返回一个 key 为 Product
的 10
资源,但仅当它属于 {{1 }} 的 key 为 Customer
那么您还可以以下列形式指定该查询:
1
或者您可以直接查询类别控制器:
~/MyService/Products(10)/Categories?$filter=Product/CustomerFK eq 1
~/MyService/Products(10)/Categories?$filter=Product/Customer/PK eq 1
虽然服务作者可以选择支持多级导航,如规范建议和 OP 所尝试的那样,但它并不总是开箱即用,因此我们往往完全忘记实现它.这并不总是很难做到,通常我们只需要实现一些简单的路由,但由于解释和实现的可变性,我个人只支持导航 1 级深度但不允许 key 选择器在子级。
如果您查询的服务不支持它,那么只需直接通过 ~/MyService/Categories?$filter=Products/any(p:p/Customer/PK eq 1 and p/Category/PK eq 10)
或通过带有适当过滤器的 Category
控制器间接定位 Cateogry
资源。