查询后修改odata结果

Modify odata results after query

我有一个 ASP.NET Web API 应用程序,使用 Entity Framework 和 Odata。

我想在使用 GET 时修改查询结果...目前,在控制器中,您实际上只是将 EntityFramework 数据实体传回 Odata 处理程序...

[EnableQuery]
public IQueryable<myEntity> GetLineItem()
{
    return db.myEntities;
}

只需返回一个子集,就可以简单地将 Odata 传递给它的任何查询放在前面

return db.myEntity.Where(myEntity => myEntity.Name == "Bob")

Odata 会将 $filter querystring 参数中的任何内容添加到此处传递的表达式中,您将获得这些结果的子集。

但是,一旦查询执行并且 SQL 结果被解析为实体对象,我想遍历结果。

我已经尝试创建一个实现 IQueryable 接口并连接到 GetEnumerator 方法的包装器,同样为 IProvider 创建一个包装器并连接到 execute 方法。 Odata 似乎没有使用其中任何一种。

有办法吗?

您可以通过实施过滤器来做到这一点。过滤器只是一个属性,您可以将其应用于操作(控制器的方法)、控制器(控制器的 class)或为整个应用程序注册。

此过滤器应用于管道的某个步骤:有一条管道从传入的 HTTP 请求到控制器操作,然后返回响应,您可以在该管道的不同位置包含一个过滤器,修改流经此管道的数据。

您特别需要继承ActionFilterAttribute,并在执行控制器操作后执行的OnActionExecuted 上进行post 处理。

文档:

最后的class是OnActuonExecuted方法的参数类型,包含了你可以修改的response

本文的第一部分包含对动作过滤器的解释: WEB API 2 USING ACTIONFILTERATTRIBUTE, OVERRIDEACTIONFILTERSATTRIBUTE AND IOC INJECTION

使用 OData 时,您不必 return 来自控制器的 IQuerable。检查 https://docs.microsoft.com/en-us/aspnet/web-api/overview/odata-support-in-aspnet-web-api/supporting-odata-query-options 的 "Invoking Query Options Directly" 部分 对于您的情况,它看起来像:

public HttpResponseMessage Get(ODataQueryOptions<myEntity> opts)
{
    var settings = new ODataValidationSettings();

    opts.Validate(settings);

    var intermediateResult = opts.ApplyTo(db.myEntities).ToArray();

    var result = //change intermediateResult as you wish.

    return result;
}

以 Ihar 的 为基础,这里有一个应用查询选项然后修改生成的集合的完整示例。

public async Task<IHttpActionResult> Get(ODataQueryOptions<MyModel> options)
{
    var query = _service.Query();

    var result = ((IQueryable<MyModel>)options.ApplyTo(query, new ODataQuerySettings()))
                                              .ToArray();

    foreach (var model in result)
    {
        model.SomeNonQueriedValue = "Something else";
    }

    return Ok(result);
}