首页 > 解决方案 > 如何将 SelectExpandQueryOption 转换为 IQueryable在 WebAPI 中使用 OData 时?

问题描述

我有一个在 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背后的代码

标签: c#asp.net-coreasp.net-web-apiodataasp.net-web-api-odata

解决方案


不能直接投

var queryable = queryOptions.SelectExpand.ApplyTo(query, settings);

to IQueryable<TModel>,因为它是不同类型的对象。

如果没有 Projection ( Select) 或 Expand - 您将得到一个常规对象,但在 Projection 和 Expand 之后 - 这是完全不同的事情。根据您的任务,您应该处理SelectAllAndExpand<TModel>或删除SelectExpand.ApplyTo(..).


推荐阅读