如何解决ODataQueryOptions.ApplyTo返回值适配SingleResult.Create的问题
解决方案
报错原因
ODataQueryOptions.ApplyTo方法默认返回非泛型IQueryable:由于OData查询选项中的$select、$apply等投影操作会修改返回的对象类型,无法保证和原始Listing实体类型一致,因此和SingleResult.Create要求的IQueryable<Listing>入参类型不匹配。
方案1:直接获取查询结果(推荐,支持所有OData查询选项)
你当前的返回结构是自定义匿名类,不需要保留SingleResult的强类型包装,直接执行查询取单条结果即可,兼容$select、$expand等所有OData标准查询选项:
[HttpPost("{key}/SpecialAction")] public IActionResult SpecialAction(Guid key, ODataQueryOptions<Listing> opts) { // 执行业务操作 var actionResults = _specialActionService.performTheAction(key); // 应用OData查询选项到单条实体的查询集合 IQueryable queryable = opts.ApplyTo(_db.Listing.Where(x => x.id == key)); // 取第一条结果,OData会自动序列化投影/扩展后的所有字段 var listing = queryable.FirstOrDefault(); return Ok(new { listing = listing, actionResults = actionResults }); }
方案2:保留SingleResult类型(仅适用于无投影的场景)
如果你确实需要使用SingleResult.Create(比如对接OData自动序列化中间件逻辑),且确认接口仅使用$expand、$orderby等不修改实体类型的查询选项,可以手动将非泛型IQueryable转为泛型:
// 仅适用于未使用$select、$apply做字段投影的场景 IQueryable<Listing> typedQueryable = queryable.Cast<Listing>(); var singleResult = SingleResult.Create(typedQueryable);
注意:如果接口需要支持
$select字段投影,禁止将查询结果强转为Listing类型,投影后的对象为OData动态生成的类型,不属于Listing实例,强转会抛出运行时异常。
内容的提问来源于stack exchange,提问作者spots
相关产品推荐
相关产品推荐

