如何像 SQL 连接一样使用 OData Expand?
实现相当于:
select *
from Users u
inner join Comments c on c.UserId = u.Id
where Id = 1569
(用于更好的 sql 可读性的表别名)
我正在尝试找出如何在 StackOverflow OData 端点上 ...。这个 url 将如何构造?我正在 OData.org 上查看 Expand 的文档,并且我会认为它看起来像:
https://odata.sqlazurelabs.com/OData.svc/v0.1/rp1uiewita/StackOverflow/Users?$Expand=Comments&$filter=UserId eq 1569 但不正确。
在 Linq 中,它会是这样的(我认为),但不支持 Join:
Users.Where(u=>u.Id==1569).Join(Comments, u=>u.Id, c=>c.UserId, (a,b)=>a.Id==b.UserId)
我不需要严格地在 Linq 中弄清楚这一点,我只是想弄清楚如何构造查询 url。基本上,如何将 SQL 连接谓词转换为 OData url 并在一次调用中完成此操作?
I'm trying to figure out how to accomplish the equivalent of:
select *
from Users u
inner join Comments c on c.UserId = u.Id
where Id = 1569
(table aliases for better sql readability)
...on the StackOverflow OData endpoint. How would this url be constructed? I'm looking at the documentation for Expand at OData.org and I would have thought it'd look something like:
https://odata.sqlazurelabs.com/OData.svc/v0.1/rp1uiewita/StackOverflow/Users?$Expand=Comments&$filter=UserId eq 1569
but isn't right.
In Linq, it would be this (I think), but Join isn't supported:
Users.Where(u=>u.Id==1569).Join(Comments, u=>u.Id, c=>c.UserId, (a,b)=>a.Id==b.UserId)
I don't need to figure this out in Linq strictly, I'm just trying to figure out how to construct the query url. Basically, how can I translate the SQL join predicate to an OData url and do this in one call?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
正确的方法是这样的:
问题是数据源中似乎没有用户(不知道为什么),所以上面的查询将返回 404。但这是正确的语法。
这个想法是,如果您只需要一个用户的信息,您可以使用
/Users(1569)
“导航”到该用户(括号中的内容是实体集的主键)。然后,如果您还想包含所有评论,只需添加$expand=Comments
即可。如果您只想要评论而不想要有关用户的信息,您可以执行/Users(1569)/Comments
。请注意,您使用的服务没有定义导航属性,因此上述内容将不起作用,因为实际上不支持“连接”。但 stackexchange odata 端点确实定义了导航属性。
基本上,连接是在服务器/服务上定义的,以便客户端不必知道哪列是哪个主键的外键。
它还有助于不使用关系数据库作为存储的数据源,因为它不会强迫它们创建假外键。
您可以进一步向下展开图表的“层”。如果展开中返回的实体还定义了更多导航属性,则您可以指定以逗号分隔的导航属性列表。
这是一个虚构服务的示例,请注意,这是扩展集合中的每个客户,这类似于多重联接。
The right way to do this would be something like:
The problem is that there seem to be no users in the data source (don't know why), so the above query will return a 404. But it is the right syntax.
The idea is that if you want information about just one user you "navigate" to it by using the
/Users(1569)
(the stuff in parethesis is the primary key of the entity set). Then if you also want to include all the comments, you simply add$expand=Comments
. If you want just the comments and not the information about the user you can do/Users(1569)/Comments
.Note that the service you used doesn't define navigation properties, so the above won't work as "joins" are not really supported. But the stackexchange odata endpoint does have the navigation properties defined.
Basically the joins are defined on the server/service so that the client doesn't have to know which column is a foreign key to which primary key.
It also helps with data sources which don't use relational databases as their storage, as it doesn't force them to create fake foreign keys.
You can expand down further "layers" of the graph. If the entity returned in the expand also defines further navigation properties, then you can specify a comma-separated list of the navigation properties.
Here's an example for a made-up service, note that this is expanding each customer in the collection, which is similar to a multiple join.