首页 > 解决方案 > OData 导航使用 $expand 而不是 url /path

问题描述

我刚刚开始使用 OData 并将其实现到我的 c# Web API 项目中。困扰我的一件事是加载导航属性时使用$expand查询而不是 url /path。

例如,通过rest api规范,如果我们要加载带有导航表(父->子)的实体,我们通常调用

/users/1/logs

结果

{
"Id": 12254,
"ApiKey": 104254635,
"FirstName": "Joshua",
"LastName": "Marcus",
"DateStamp": "2019-06-11T06:43:11.897+03:00",
"TimeZone": "UTC",
"Logs":[
{"Id": 74216060, "Result": true, "DateStamp": "2019-06-11T06:51:17.487+03:00", "ConversionTime": 3,…},
{"Id": 74215748, "Result": false, "DateStamp": "2019-06-11T06:50:11.117+03:00", "ConversionTime": 3,…}
]
}

加载导航属性的 OData 改为使用查询参数

/users/1?$expand=logs

这有点奇怪,并且看起来超出了 Rest API 规范来查询这样的资源。也许有人可以对此发表评论并提供更多信息,说明为什么在 OData 中使用这种解决方案,是否可以使用通用父/子结构来使用 OData 查询相关记录?

标签: c#restodata

解决方案


选项$expand仅告诉服务将您的导航元素与您对父实体的请求的结果内联返回。您应该能够logs使用您的 url 访问实体集/users/1/logs,并且通常它应该返回一个实体数组log,但没有父实体属性。但是,如果您希望您的父实体和(扩展的)日志都在一个请求和结果中,则需要使用 $expand 选项。将其视为在获取分层数据集时减少查询数量的一种方法。使用 $expand 您还可以决定要扩展哪些子导航属性(以及扩展到哪个级别)。

使用此 OData v2 测试服务,您可以请求一个Product实体并使用 $expand 选项不仅扩展供应商,而且扩展供应商的所有产品:

服务的基本 url:https ://services.odata.org/V2/(S(readwrite))/OData/OData.svc/ (服务用随机字符串替换它的部分 url,所以你会看到在浏览器中打开基本 url 后,此 url 的略微修改版本)。

并且根据对您的请求,Products(0)?$expand=Supplier/Products您将获得 ID 为 0 的产品、其供应商与产品内联,以及供应商的所有产品与供应商内联。但是,如果您请求Products(0)/Supplier/Products,您将仅收到一组product实体,而没有您最初请求的产品的供应商数据或属性(尽管在这种情况下它也包含在列表中)。


推荐阅读