MapODataRoute和ODataQueryOptions

时间:2013-11-13 10:25:15

标签: asp.net-web-api odata

我正在构建一个处理无类型实体对象的WebAPI OData解决方案,如this excellent post中所述。就像那篇文章一样,我预先定义了我的EdmModel,并使用MapODataRoute方法并传入模型使用:

config.Routes.MapODataRoute("odata", "odata", ModelBuilder.GetEdmModel());

但是,这似乎不适用于我的方法中的ODataQueryOptions参数:

Get(ODataQueryOptions query)
{
}

它给出以下错误:给定的模型不包含类型'System.Web.Http.OData.IEdmEntityObject'。参数名称:elementClrType

有没有办法让ODataQueryOptions与MapODataRoute一起使用?

2 个答案:

答案 0 :(得分:3)

您应该在非类型模式下在控制器操作中手动构建ODataQueryOptions。示例代码如下,

ODataPath path = Request.GetODataPath();
IEdmType edmType = path.EdmType;

IEdmType elementType = edmType.TypeKind == EdmTypeKind.Collection 
    ? (edmType as IEdmCollectionType).ElementType.Definition 
    : edmType;

// build the typeless query options using the element type.
ODataQueryContext queryContext = new ODataQueryContext(Request.GetEdmModel(), elementType);
ODataQueryOptions queryOptions = new ODataQueryOptions(queryContext, Request);

答案 1 :(得分:0)

我设法做到如下:

ODataPath path = Request.GetODataPath();
IEdmType edmType = path.EdmType;   

private ODataQueryOptions GetODataQueryOptions(IEdmType edmType)
    {
        IEdmModel model = Models.ModelBuilder.GetEdmModel();
        ODataQueryContext queryContext = new ODataQueryContext(model, edmType);
        ODataQueryOptions queryOptions = new ODataQueryOptions(queryContext, this.Request);

        return queryOptions;
    }

这适用于大多数查询选项,但是使用$ select和$ expand崩溃:类型'Collection([Org.Microsoft.Product Nullable = False])'不是实体类型。只有实体类型支持$ select和$ expand。有一种方法可以在客户端尝试使用$ select和$ expand进行过滤时优雅地避免此异常,或者我应该写一些类似

的内容
if (Request.RequestUri.Query.Contains("select")) { return errormessage }

此外,更重要的是,如何将这些查询选项应用于第一个方法中返回的 EdmEntityObjectCollection

queryOptions.ApplyTo(collectionProduct.AsQueryable()); // wont work...

(或许最好动态构建关于查询选项的集合)