Web API 2.2 - 当$ select或$ expand存在时,OData v4 ODataQueryOptions.applyTo()返回null?

时间:2015-03-17 15:02:26

标签: odata asp.net-web-api asp.net-web-api2 odata-v4

我已经设置了一个Web API 2.2 ODataController,这样我就可以手动处理我的OData选项(即没有[EnableQuery]和/或使用ODataQueryOptions参数)。但是我遇到了一个看起来像个bug的东西。给出以下代码:

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);

将从

返回null
employees = newOptions.ApplyTo(employees) as IQueryable<Employee>;

这迫使我创建两个单独的ODataQueryOptions,一个用于应用IQueryable(没有任何$ select或$ expand),另一个只用$ choices / $ expand来构建SelectExpandClause以分配给Request.ODataProperties() .SelectExpandClause。

我只是不明白为什么会发生null返回。此代码背后的核心意图是,在使用Entity Framework以外的ORM时,可以更好地控制处理OData。所以说实话,我最终会覆盖applyTo(或者只是自己手动处理表达式树),但这个特殊的例子对我来说似乎仍然是一个错误。

有人能给我一些见解吗?也许我只是缺少一些东西。

1 个答案:

答案 0 :(得分:5)

(将上面的评论移到答案上)

因为你真正从ApplyTo获得的东西(一旦你添加$ select或$ expand)就是

System.Web.OData.Query.Expressions.SelectExpandBinder.SelectAllAndExpand<Employe‌​e>

当然,不能转换为IQueryable,因此为null。

为什么不添加EnableQuery属性,并返回IQueryable(而不是ToList)?