查询后修改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);
}
我有一个 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);
}