我正在构建一个 OData v.4 Web 服务,该服务必须公开从另一个第 3 方 Web 源检索的数据,因此该数据与 LINQ 世界中的任何内容都不相同,即:没有 IQueryable,没有 Context,什么都没有。
解决方法似乎是手动处理来自 ODataQueryOptions 的参数并返回简单的项目序列。因此,控制器方法应该如下所示:
class MyMasterEntity {
[Contained]
public IEnumerable<MyDetailEntity> Details { get; set; }
}
// [EnableQuery]
public IEnumerable<MyMasterEntity> Get(ODataQueryOptions<MyMasterEntity> options)
{
// process .FilterQueryOption
// process .SelectExpandQueryOption
// process .SkipQueryOption
// process .TopQueryOption
return myMasterEntityList;
}
这很有效,除了$expand=Details
,在这种情况下,属性不会在结果响应中扩展,尽管我的逻辑将它们添加得很好。
如果添加[EnableQuery]
属性(一开始就没有意义,因为它与 ODataQueryOptions 的整个思想是互斥的),然后扩展开始工作。或者更确切地说pretends工作,因为真正发生的是查询被处理两次:第一次由我的代码处理,然后在我返回数据后由 OData 机器处理。这可能是可以忍受的(无论如何,我手动执行昂贵的调用,因此 OData 重试已准备好的数据没什么大不了的),如果不是因为第二遍会破坏像 $skip 这样的非确定性操作。 (即:可以多次应用 $top 来获得相同的结果,但不能使用 $skip 来执行此操作)。
正如我从逆向工程相关程序集了解到的,标准扩展代码将实体包装成某种东西,这告诉 JSON 格式化程序发出相应的属性,无论它们是否实际上在实体内扩展。
还尝试过:
- 更改返回类型(IQueryable、IHttpActionResult)
- 强制呼叫
SelectExpandQueryOption.ApplyTo(myMasterEntityList, new ODataQuerySettings())
手动扩展之后,返回之前
如何正确扩展导航属性?
为什么要手动处理查询选项?
Use the AsQueryable
LINQ 扩展方法将您的数据转换为可查询的集合(实际上您正在使用 LINQ to Object)。
- 你的控制器必须继承自
ODataController
- An
IEdmModel
必须与路线相关联。使用 ODataModelBuilder(或 ODataConventionModelBuilder)定义它。
- 你的方法必须返回
IQueryable<MyMasterEntity>
- 仅声明
[EnableQuery]
。不要显式声明ODataQueryOptions
争论
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)