OData-v4 - 对实体集合进行操作然后执行函数
OData-v4 - operating on an entity collection then performing a Function
在我的 ODATA-v4 控制器中,我有以下代码:
var fn = reportModelBuilder.EntityType<CurrentTestResult>()
.Collection.Function("Breakdown").Returns<int>();
在CurrentTestResultController.cs中,我有看似简单的:
[EnableQuery(AllowedQueryOptions = AllowedQueryOptions.All)]
[HttpGet]
public IHttpActionResult Breakdown()
{
var count = dataService.GetAll()
.Select(x => x.TestResultTypeId)
.Distinct()
.Count();
return Ok(count);
}
本质上,对于集合中的所有 CurrentTestResult
个实体,它 return 是集合中出现的不同 TestResultTypeId
。 (这是一个微不足道的操作,但我简化了一个复杂得多的真实生活场景)
这很容易做到 - 但我似乎无法首先 过滤它应该操作的 CurrentTestResult
集合。
此请求,默认情况下对所有 CurrentTestResult 实体进行操作
localhost/app/odatareport/CurrentTestResult/Default.细目
return秒
{
@odata.context: "http://localhost/app/odatareport/$metadata#Edm.Int32",
value: 5
}
(一个正确的结果,有 5 种不同的类型)
但是,这个试图首先简单地过滤它的请求失败了
localhost/app/odatareport/CurrentTestResult/Default.故障?$top=2
return秒
{
error: {
code: "",
message: "The query specified in the URI is not valid. The requested resource is not a collection. Query options $filter, $orderby, $count, $skip, and $top can be applied only on collections.",
innererror: {
message: "The requested resource is not a collection. Query options $filter, $orderby, $count, $skip, and $top can be applied only on collections.",
type: "Microsoft.OData.ODataException",
stacktrace:
" at System.Web.OData.EnableQueryAttribute.ValidateSelectExpandOnly(ODataQueryOptions queryOptions) at System.Web.OData.EnableQueryAttribute.ExecuteQuery(Object response, HttpRequestMessage request, HttpActionDescriptor actionDescriptor, ODataQueryContext queryContext) at System.Web.OData.EnableQueryAttribute.OnActionExecuted(HttpActionExecutedContext actionExecutedContext)"
}
}
}
据我了解 ODATA 管道,为什么失败是有道理的。控制器方法将 return 一个 IQueryable,然后将应用 ODATA $filter、$top 等。
我想要一个函数来对已经被过滤掉的集合进行操作。
我想做的事情是否可行?
我知道 Breakdown 方法本身有 .GetAll(),但一定有一种方法可以在该方法之前应用过滤 -
否则,这一切都毫无意义....
两个选项:
1) ODATA 有一个 $count
端点(参见 this 但有两种形式的 $count
- 一个端点 api/collection/$count
和一个系统查询选项 api/collection?$count=true
; 你会想要 return 集合计数的端点(可以用 EnableQuery
过滤)。将您的函数视为任何其他 GET
收集方法和 return 您希望计数的查询(在本例中,不同 TestResultTypeId
),然后只需要求客户端请求其 $count
端点。
2) 为您的操作方法定义一个 ODataQueryOptions<T>
参数并手动应用选项:
public IHttpActionResult Get( ODataQueryOptions<CurrentTestResult> queryOptions )
{
// base query with ODataQueryOptions applied
var query = queryOptions.ApplyTo( dataServcie.GetAll() )
as IQueryable<CurrentTestResult>;
// get distinct TestResultTypeId's and then count
var count = query.Select(x => x.TestResultTypeId)
.Distinct()
.Count();
return Ok( count );
}
我现在在移动,所以无法测试,但这应该足够接近(如果不准确的话)让你到达你需要去的地方。如果有任何问题,请告诉我,我会更新答案。
在我的 ODATA-v4 控制器中,我有以下代码:
var fn = reportModelBuilder.EntityType<CurrentTestResult>()
.Collection.Function("Breakdown").Returns<int>();
在CurrentTestResultController.cs中,我有看似简单的:
[EnableQuery(AllowedQueryOptions = AllowedQueryOptions.All)]
[HttpGet]
public IHttpActionResult Breakdown()
{
var count = dataService.GetAll()
.Select(x => x.TestResultTypeId)
.Distinct()
.Count();
return Ok(count);
}
本质上,对于集合中的所有 CurrentTestResult
个实体,它 return 是集合中出现的不同 TestResultTypeId
。 (这是一个微不足道的操作,但我简化了一个复杂得多的真实生活场景)
这很容易做到 - 但我似乎无法首先 过滤它应该操作的 CurrentTestResult
集合。
此请求,默认情况下对所有 CurrentTestResult 实体进行操作
localhost/app/odatareport/CurrentTestResult/Default.细目
return秒
{
@odata.context: "http://localhost/app/odatareport/$metadata#Edm.Int32",
value: 5
}
(一个正确的结果,有 5 种不同的类型)
但是,这个试图首先简单地过滤它的请求失败了
localhost/app/odatareport/CurrentTestResult/Default.故障?$top=2
return秒
{
error: {
code: "",
message: "The query specified in the URI is not valid. The requested resource is not a collection. Query options $filter, $orderby, $count, $skip, and $top can be applied only on collections.",
innererror: {
message: "The requested resource is not a collection. Query options $filter, $orderby, $count, $skip, and $top can be applied only on collections.",
type: "Microsoft.OData.ODataException",
stacktrace:
" at System.Web.OData.EnableQueryAttribute.ValidateSelectExpandOnly(ODataQueryOptions queryOptions) at System.Web.OData.EnableQueryAttribute.ExecuteQuery(Object response, HttpRequestMessage request, HttpActionDescriptor actionDescriptor, ODataQueryContext queryContext) at System.Web.OData.EnableQueryAttribute.OnActionExecuted(HttpActionExecutedContext actionExecutedContext)"
}
}
}
据我了解 ODATA 管道,为什么失败是有道理的。控制器方法将 return 一个 IQueryable,然后将应用 ODATA $filter、$top 等。
我想要一个函数来对已经被过滤掉的集合进行操作。
我想做的事情是否可行?
我知道 Breakdown 方法本身有 .GetAll(),但一定有一种方法可以在该方法之前应用过滤 -
否则,这一切都毫无意义....
两个选项:
1) ODATA 有一个 $count
端点(参见 this 但有两种形式的 $count
- 一个端点 api/collection/$count
和一个系统查询选项 api/collection?$count=true
; 你会想要 return 集合计数的端点(可以用 EnableQuery
过滤)。将您的函数视为任何其他 GET
收集方法和 return 您希望计数的查询(在本例中,不同 TestResultTypeId
),然后只需要求客户端请求其 $count
端点。
2) 为您的操作方法定义一个 ODataQueryOptions<T>
参数并手动应用选项:
public IHttpActionResult Get( ODataQueryOptions<CurrentTestResult> queryOptions )
{
// base query with ODataQueryOptions applied
var query = queryOptions.ApplyTo( dataServcie.GetAll() )
as IQueryable<CurrentTestResult>;
// get distinct TestResultTypeId's and then count
var count = query.Select(x => x.TestResultTypeId)
.Distinct()
.Count();
return Ok( count );
}
我现在在移动,所以无法测试,但这应该足够接近(如果不准确的话)让你到达你需要去的地方。如果有任何问题,请告诉我,我会更新答案。