在 WebAPI 中使用 OData 时如何将 SelectExpandQueryOption 转换为 IQueryable<T>?
Posted
技术标签:
【中文标题】在 WebAPI 中使用 OData 时如何将 SelectExpandQueryOption 转换为 IQueryable<T>?【英文标题】:How to cast SelectExpandQueryOption to IQueryable<T> when using OData in WebAPI? 【发布时间】:2021-12-01 06:08:40 【问题描述】:我有一个在 ASP.NET Core/5 框架之上用 C# 编写的 WebAPI。
我为我的 API 启用了odata。我正在尝试手动应用 odata 过滤器、order by 子句、选择列和扩展。
这是我尝试使用 ODataQueryOptions
手动构建查询的方式
protected IQueryable<TModel> BuildQuery(ODataQueryOptions<TModel> queryOptions, ODataQuerySettings settings)
IQueryable<TModel> query = DbSet;
if (queryOptions.SelectExpand != null)
var queryable = queryOptions.SelectExpand.ApplyTo(query, settings);
query = queryable.Cast<TModel>(); // this causes an error
if (queryOptions.Filter != null)
query = queryOptions.Filter.ApplyTo(query, settings) as IQueryable<TModel>; // this works!
if (queryOptions.OrderBy != null)
query = queryOptions.OrderBy.ApplyTo(query); // this works!
return query;
在我尝试扩展导航属性之前,上面的一切都很好。当我这样做时,我收到以下错误
System.InvalidOperationException: 'No coercion operator is defined between types 'Microsoft.AspNetCore.OData.Query.Wrapper.SelectAllAndExpand`1[MyModel]' and 'MyModel'.'
在定义IEdmModel
以构建导航关系时,是否需要进行某种映射?
如何正确地将IQueryable<Microsoft.AspNetCore.OData.Query.Wrapper.SelectAllAndExpand<TEntity>>
转换/转换为IQueryable<TEntity>
?
这是SelectAllAndExpand背后的代码
【问题讨论】:
可能是 ***.com/questions/55636167/… 的副本,您无法将 selectexpand 查询转换为已定义的模型,您需要将其转换为动态,想象当query
是 IEnumerablequery.Select(t => new t.Id, t.Name )
这个查询不能被强制转换为 IEnumerable你不能直接投射
var queryable = queryOptions.SelectExpand.ApplyTo(query, settings);
到IQueryable<TModel>
,因为它是不同类型的对象。
如果没有 Projection (Select
) 或 Expand - 您将得到一个常规对象,但在 Projection 和 Expand 之后 - 这是完全不同的事情。
根据您的任务,您应该处理SelectAllAndExpand<TModel>
或删除SelectExpand.ApplyTo(..)
。
【讨论】:
以上是关于在 WebAPI 中使用 OData 时如何将 SelectExpandQueryOption 转换为 IQueryable<T>?的主要内容,如果未能解决你的问题,请参考以下文章
您如何将乐观并发与 WebAPI OData 控制器一起使用
使用 EF 和 WebAPI,如何返回 ViewModel 并支持 IQueryable/OData? [复制]