LINQ与OData的结合

本文关键字:结合 OData LINQ | 更新日期: 2023-09-27 18:03:27

OData的限制(在这里列出)阻止我向来自OData数据源的数据集添加动态where子句。我找到了之前的一篇文章,回答了我对动态过滤器的查询,这是使用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子句生成"and"过滤器,而不是"or"过滤器,如下所示:

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

我想知道是否有一种方法可以手动编辑字符串,或者是否有一种合适的方法来组合两个查询字符串生成方法。感谢您的宝贵时间。

LINQ与OData的结合

经过一些尝试和错误之后,我发现使用这里回答的解决方案有助于解决这个问题。我的解决方案是在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))

这里的技巧是确保查询中只有一个"$filter"选项,否则将抛出异常。

如果在调用GetDynamicQuery(assets);之前where子句中已经存在DateTime过滤器,则会给您一个错误错误将类似于使用新请求Url 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时的错误我已经在这个链接上发布了这个方程