问题描述
当我应该继承我的控制器形式ODataController
vs ApiController
时有人可以解释一下吗?
Can someone explain me when I should inherit my controller form ODataController
vs ApiController
?
该问题是由ApiController
返回的结果可以使用OData查询过滤的事实引起的.
The question is caused by the fact that results returned by ApiController
can be filtered with OData query.
如果我将QueraybleAttribute
应用于contoller的方法,则即使操作返回IEnumerable
,也会处理查询.
但是,如果没有此属性,但调用为config.EnableQuerySupport()
,则仅当方法返回IQueryable
时才处理查询.
我认为这不是一致的行为. WebAPI 文档和示例暗示该控制器必须从ODataController继承.而且我有点困惑.ApiController
accidentally
并部分支持OData协议的一部分(至少$ skip,$ filter和$ top).或这是设计使然,我需要ODataController以获得完整的ODataSupport.
If I apply QueraybleAttribute
to contoller's methods, query is processed even if action returns IEnumerable
.
However without this attribute but with the call config.EnableQuerySupport()
, query is processed only if method returns IQueryable
.
I think it is not consistent behavior. WebAPI documentation and examples imply that controller must inerit from ODataController. And I'm a little confused.
Either ApiController
accidentally
and partially supports part (at least $skip, $filter and $top) of OData protocol. Or this is by design and I need ODataController for complete ODataSupport.
真正的问题是我的服务公开了DTO,而不是POCO.可能没有一对一的映射.需要将OData查询Againts DTO转换为针对POCO的EF查询.
现在只玩OData.我检索实体并将其转换为DTO.诚然,对于每个请求都可以从数据库中获取所有消息,但还不能进行实验,这并不是很有效.但是,如果需要一些经过筛选的DTO子集,则绝对不需要将所有实体返回给客户端.
OData查询开始使用ApiController和Querayble属性开箱即用,但是上述不一致使我做错了事情.
The real problems is that my service exposes DTOs, not POCOs. There may be no one to one mappings. There's need to convert OData query againts DTOs to EF query against POCOs.
Now just playing with OData. I retrieve entities and convert them to DTOs. Admittedly, this is not very performant to get all of them from DB for each request yet tolerale for experiments. But there's definetely no need to return all entities to the client if it requires some filtered subset of DTOs.
OData query started working out of the box with ApiController and Querayble attribute, but the aforementioned inconsistency makes me thing I doing something wrong.
推荐答案
如果要公开遵循 OData协议.如果要执行其他操作(例如REST端点),请从ApiController
继承.
You would want to inherit from ODataController
if you want to expose an endpoint that adheres to the OData protocol. If you want to do something else, such as a REST endpoint, then inherit from ApiController
.
应用WebAPI OData框架的某些部分而不应用其他部分可能不是一个好主意.在某些情况下可能会,但在其他情况下可能效果不佳.例如,您可能会获得查询支持,但可能不会生成$ metadata端点(这只是推测,实际症状可能有所不同).
Applying some parts of the WebAPI OData framework but not others is probably not a good idea. It may in some cases, but will probably not work well in others. For example you may get querying support, but the $metadata endpoint may not be generated (that's just speculation, the actual symptoms may be different).
听起来您已经在使用EntityFramework.我知道有许多示例显示如何将其公开为OData端点.
It sounds like you're using EntityFramework already. I know there are a number of samples showing how to expose that as an OData endpoint.
如果由于某种原因而不想这样做,则可以实现自己的查询.在本教程,但要点是在操作中添加ODataQueryOptions<T>
类型的参数,并使用其上的方法过滤结果集.但是,为所有可能的OData查询生成良好的数据库查询可能会很痛苦,因此,如果可能的话,应该避免这种情况.
If you don't want to do that for some reason, you can implement querying yourself. This is briefly covered in a few places on this tutorial, but the gist is to add a parameter of type ODataQueryOptions<T>
to your action, and use the methods on it to filter your result set. However, it can be painful to generate good database queries for all possible OData queries, so you should avoid that if possible.
这篇关于公开DTO时的ApiController与ODataController的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!