Web API 2.2 - OData v4 ODataQueryOptions.applyTo() 在 $select 或 $expand 存在时返回空值?
Web API 2.2 - OData v4 ODataQueryOptions.applyTo() returning null when $select or $expand present?
我已经设置了一个 Web API 2.2 ODataController,这样我就可以手动处理我的 OData 选项(即不使用 [EnableQuery] 和/或使用 ODataQueryOptions 参数)。但是我 运行 发现了一个看起来像错误的东西。给定以下代码:
public IHttpActionResult GetEmployees() {
//Get Queryable Item (in this case just an in-memory List made queryable)
IQueryable<Employee> employees = _Employees.AsQueryable();
//Get Requested URI without querystring (there may be other ways of doing this)
String newUri = Request.RequestUri.AbsoluteUri;
if (!String.IsNullOrEmpty(Request.RequestUri.Query)) {
newUri = newUri.Replace(Request.RequestUri.Query, "");
}
//Add custom OData querystring (this is for example purposes)
newUri = String.Format("{0}?$skip={1}&$top={2}", newUri, 1, 1);
//Create new HttpRequestMessage from the updated URI
HttpRequestMessage newRequest = new HttpRequestMessage(Request.Method, newUri);
//Create new ODataQueryContext based off initial request (required to create ODataQueryOptions)
ODataQueryContext newContext = new ODataQueryContext(Request.ODataProperties().Model, typeof(Employee), Request.ODataProperties().Path);
//Create new ODataQueryOptions based off new context and new request
ODataQueryOptions<Employee> newOptions = new ODataQueryOptions<Employee>(newContext, newRequest);
//Apply the new ODataQueryOptions to the Queryable Item
employees = newOptions.ApplyTo(employees) as IQueryable<Employee>;
//Return List (will be serialized by OData formatter)
return Ok(employees.ToList());
}
100% 有效,但是添加 $select 或 $expand 如下:
newUri = String.Format("{0}?$skip={1}&$top={2}&$expand=Projects", newUri, 1, 1);
将从
return 为空
employees = newOptions.ApplyTo(employees) as IQueryable<Employee>;
这迫使我创建两个单独的 ODataQueryOptions,一个应用到 IQueryable(没有任何 $select 或 $expand),另一个只应用 $selects/$expands 到构建 SelectExpandClause 以分配给 Request.ODataProperties().SelectExpandClause.
我只是不明白为什么会出现空 return。此代码背后的核心意图是在使用 Entity Framework 以外的 ORM 时允许更好地控制处理 OData。所以实际上我最终会覆盖 applyTo 无论如何(或者只是自己手动处理表达式树),但这个特定的例子对我来说仍然像是一个错误。
任何人都可以给我一些见解吗?也许我只是缺少一些东西。
(将我的评论移至答案上方)
因为您从 ApplyTo 真正得到的(一旦您添加 $select 或 $expand)是
System.Web.OData.Query.Expressions.SelectExpandBinder.SelectAllAndExpand<Employee>
这当然不能转换为 IQueryable,因此为 null。
为什么不添加 EnableQuery 属性和 return IQueryable(而不是 ToList)?
我已经设置了一个 Web API 2.2 ODataController,这样我就可以手动处理我的 OData 选项(即不使用 [EnableQuery] 和/或使用 ODataQueryOptions 参数)。但是我 运行 发现了一个看起来像错误的东西。给定以下代码:
public IHttpActionResult GetEmployees() {
//Get Queryable Item (in this case just an in-memory List made queryable)
IQueryable<Employee> employees = _Employees.AsQueryable();
//Get Requested URI without querystring (there may be other ways of doing this)
String newUri = Request.RequestUri.AbsoluteUri;
if (!String.IsNullOrEmpty(Request.RequestUri.Query)) {
newUri = newUri.Replace(Request.RequestUri.Query, "");
}
//Add custom OData querystring (this is for example purposes)
newUri = String.Format("{0}?$skip={1}&$top={2}", newUri, 1, 1);
//Create new HttpRequestMessage from the updated URI
HttpRequestMessage newRequest = new HttpRequestMessage(Request.Method, newUri);
//Create new ODataQueryContext based off initial request (required to create ODataQueryOptions)
ODataQueryContext newContext = new ODataQueryContext(Request.ODataProperties().Model, typeof(Employee), Request.ODataProperties().Path);
//Create new ODataQueryOptions based off new context and new request
ODataQueryOptions<Employee> newOptions = new ODataQueryOptions<Employee>(newContext, newRequest);
//Apply the new ODataQueryOptions to the Queryable Item
employees = newOptions.ApplyTo(employees) as IQueryable<Employee>;
//Return List (will be serialized by OData formatter)
return Ok(employees.ToList());
}
100% 有效,但是添加 $select 或 $expand 如下:
newUri = String.Format("{0}?$skip={1}&$top={2}&$expand=Projects", newUri, 1, 1);
将从
return 为空employees = newOptions.ApplyTo(employees) as IQueryable<Employee>;
这迫使我创建两个单独的 ODataQueryOptions,一个应用到 IQueryable(没有任何 $select 或 $expand),另一个只应用 $selects/$expands 到构建 SelectExpandClause 以分配给 Request.ODataProperties().SelectExpandClause.
我只是不明白为什么会出现空 return。此代码背后的核心意图是在使用 Entity Framework 以外的 ORM 时允许更好地控制处理 OData。所以实际上我最终会覆盖 applyTo 无论如何(或者只是自己手动处理表达式树),但这个特定的例子对我来说仍然像是一个错误。
任何人都可以给我一些见解吗?也许我只是缺少一些东西。
(将我的评论移至答案上方)
因为您从 ApplyTo 真正得到的(一旦您添加 $select 或 $expand)是
System.Web.OData.Query.Expressions.SelectExpandBinder.SelectAllAndExpand<Employee>
这当然不能转换为 IQueryable,因此为 null。
为什么不添加 EnableQuery 属性和 return IQueryable(而不是 ToList)?