将LINQ与OData AddQueryOption相结合

时间:2015-07-20 09:49:04

标签: c# .net linq odata

OData的限制(listed here)阻止我从我的OData源添加动态where子句到数据集。我找到了一个previous post来回答我对动态过滤器的查询,即使用AddQueryOption方法和自定义构建的查询字符串。但是,似乎没有办法将此查询字符串与标准LINQ查询组合在一起。

使用上述方法生成有效查询:

https://api-dev.company.com/odata/Assets?$filter=(Levels/any(l:l/LevelId eq 18)) or (Levels/any(l:l/LevelId eq 19))

必须动态生成的原因是因为存在可变数量的级别过滤器,这些级别过滤器在运行时之前无法确定并且仅使用多个Where子句生成"和"过滤器代替"或"过滤器,像这样:

https://api-dev.company.com/odata/Assets?$filter=(Levels/any(l:l/LevelId eq 18)) and (Levels/any(l:l/LevelId eq 19))

我目前尝试在此方法后使用LINQ产生输出:

https://api-dev.company.com/odata/Assets?$filter=DisplayOnline and Status eq Tools.Services.Models.EPublishStatus'Active', and (Levels/any(l:l/LevelId eq 18)) or (Levels/any(l:l/LevelId eq 19))

请注意,第二个查询只是错误的是Levels过滤器和其他过滤器之间的逗号。

其他Where子句如下:

// Filter by assets that can be displayed online
assets = assets.Where(a => a.DisplayOnline);

// Filter by assets that are active
assets = assets.Where(a => a.Status == EPublishStatus.Active);

我想知道是否有办法手动编辑字符串,或者是否有合适的方法来组合两种查询字符串生成方法。谢谢你的时间。

2 个答案:

答案 0 :(得分:2)

经过一些反复试验后,我发现使用解决方案answered here有助于解决此问题。我的解决方案是在LINQ Where子句之后构建动态过滤器查询,然后使用两者的组合结果构建一个全新的查询:

// Filter by assets that can be displayed online
assets = assets.Where(a => a.DisplayOnline);

// Filter by assets that are active
assets = assets.Where(a => a.Status == EPublishStatus.Active);

// Addtional filters..
assets = assets.Where(a => x == y);

// Get the string for the dynamic filter
string dynamicQuery = GetDynamicQuery(assets);

// Get base OData Asset call (https://api-dev.company.com/odata/Assets)
IQueryable<Asset> serviceCall = _container.Assets;

// Apply the new dynamic filter
serviceCall = serviceCall.AddQueryOption("$filter", dynamicQuery);

// Resultant OData query (Success!)
https://api-dev.company.com/odata/Assets?$filter=DisplayOnline and Status eq Models.Status'Active' and (Levels/any(l:l/LevelId eq 18)) or (Levels/any(l:l/LevelId eq 19))

这里的诀窍是确保只有一个&#34; $ filter&#34;查询中的选项,否则将抛出异常。

答案 1 :(得分:0)

如果在调用GetDynamicQuery(assets);之前where子句中已存在DateTime过滤器,则会出现错误 使用新的请求网址message=The time zone information is missing on the DateTimeOffset value '2016-09-20T23:54:23.4531408'. A DateTimeOffset value must contain the time zone information.调用odata web api时会出现错误 我已经在link

上发布了这个问题