如何使用 C# 为 OData 查询中指定的每个过滤器获取一组键/值对?

Posted

技术标签:

【中文标题】如何使用 C# 为 OData 查询中指定的每个过滤器获取一组键/值对?【英文标题】:How can I obtain a set of Key/Value pairs for each filter specified in an OData query using C#? 【发布时间】:2014-10-15 22:37:28 【问题描述】:

我有一个接受 OData 查询的 ASP.Net WebAPI 服务。我的控制器方法之一接受ODataQueryOptions 实例并将其应用于IQueryable 实例。到现在为止还挺好。一切都按计划进行。

现在,我特别需要从 OData 查询中获取其中一个键/值对。例如,如果我指定了两个过滤器(someproperty eq 123 and otherproperty eq 456),我如何从原始过滤器中获取其中一个键/值对?我查看了一些 ODataUriParser 文档,但它确实很复杂,而且看起来有点矫枉过正。有没有更简单的方法来获取简单的键/值对,就像我从普通的 QueryString 中获取的一样?

编辑:我已经进行了一些手动字符串解析来完成我所需要的,但这显然并不理想。因此,我在这个问题上悬赏。希望有人对此有一个简单的解决方案!

【问题讨论】:

您能否展示您已经拥有的源代码(可能带有一些模拟数据和选项/过滤器)? 看看This基于正则表达式的解决方案。 您希望如何访问此过滤器?您在谈论 like I would from a normal QueryString 这不是查询字符串,因为它具有和/或/不是运算符。我想理想是解析为表达式树,但框架会为你做这件事。我有一个实现 IQueryable 并将其传递给 OData 的示例。 @Pavel:我已经有了这样的实现并在其他任何地方使用它,但是通过这个查询,我需要知道是否有一种方法可以让我从原始 odata 查询中推断出键值对本身。为此,我什至不关心 and/or/not 运算符。 @Glk.net:这太完美了!它仍然需要手动解析原始查询,但它做得很好。我可以把它包装在一些 C# 代码中,给它一个更客观的结构,我就完成了。谢谢你!您能否发布一些使用该用法的内容作为答案,以便我奖励您赏金? 【参考方案1】:

有一种使用正则表达式的简单方法,您可以将 Odata 查询过滤器转换为键值对,从这个答案Here 中找到正则表达式

string strRegex = @"(?<Filter>" + 
"\n" + @"     (?<Resource>.+?)\s+" + 
"\n" + @"     (?<Operator>eq|ne|gt|ge|lt|le|add|sub|mul|div|mod)\s+" + 
"\n" + @"     '?(?<Value>.+?)'?" + 
"\n" + @")" + 
"\n" + @"(?:" + 
"\n" + @"    \s*$" + 
"\n" + @"   |\s+(?:or|and|not)\s+" + 
"\n" + @")" + 
"\n";

您的替换字符串类似于,

string strReplace = @"$Resource:$Value," 

这会给你这样的输出,

someproperty:123,otherproperty:456

然后将该字符串转换为您的 KeyValue 参数的字典,或者您想使用它

public Dictionary<String, String> getKeyValue(String input)
    

           return input.Split(',').ToDictionary(kv => kv.Split(':').First(), kv => kv.Split(':').Last());

    

【讨论】:

以上是关于如何使用 C# 为 OData 查询中指定的每个过滤器获取一组键/值对?的主要内容,如果未能解决你的问题,请参考以下文章

OData 异常已超出 Top 查询的“0”限制

如何在C#中获取连接字符串中指定的Mongo数据库

C#如何读取XML中指定的节点值?

c#怎么获得dataGridView中指定的列的内容

在构建 Java GraphQL API 时,如何避免从数据库中过度获取(即仅获取查询中指定的字段)?

如果满足另一个中指定的条件,则更新查询在其中一个中更新数据