OData 4带有浮动的客户端和过滤器



我们使用OData4 Client Generator来创建一些代理类并查询OData4服务。一切似乎都很好,除了我们想通过浮点或双精度属性进行过滤的查询。

对于使用整数过滤器的给定查询:

var ctx = new ODataClient(new Uri("http://..."));
var intFilter = 3;
var results = ctx.Entities.Where(e => e.IntProperty == intFilter).ToList();
对服务的查询结果为:
Entities?$filter=IntProperty eq 3

我们得到过滤后的结果,如预期的那样。

但是如果我们尝试使用双精度值进行过滤,例如:

var ctx = new ODataClient(new Uri("http://..."));
var doubleFilter = 0.35d;
var results = ctx.Entities.Where(e => e.DoubleProperty == doubleFilter).ToList();

结果查询最终为:

Entities?$filter=DoubleProperty eq 0.35

实际上应该是:

Entities?$filter=DoubleProperty eq 0.35d

最后的微小差异导致服务抛出异常:

The query specified in the URI is not valid. 
Numeric string '0.35' is not a valid Int32/Int64/Double/Decimal.

是否有任何方法来配置这些代理客户端正确地进行转换?或者我们被AddQueryOption方法困住了,不得不"手动"构建我们的过滤器,而不是用LINQ?

Entities?$filter=DoubleProperty eq 0.35实际上是一个期望的表达式,如果你看一下OData协议5.1.1.6.1原始文字

基本字面值可以作为关键属性值出现在资源路径中,也可以作为查询部分的操作数出现在$filter表达式中。它们是根据[OData-ABNF]中的primitivelital规则表示的。

OData-ABNF对PrimitiveLiteral的定义如下:

;在url

primitiveLiteral = nullValue                  ; plain values up to int64Value
             / ...
             / doubleValue 
             / singleValue 
             / ...
decimalValue = [SIGN] 1*DIGIT ["." 1*DIGIT]
doubleValue = decimalValue [ "e" [SIGN] 1*DIGIT ] / nanInfinity ; IEEE 754 binary64 floating-point number (15-17 decimal digits)
singleValue = doubleValue 

所以我认为你们的服务支持最好能把0.35提升一倍。

要解决这个问题,实际上你可以像下面这样使用AddQueryOption

ctx.Entities.AddQueryOption("$filter", "DoubleProperty eq 0.35d").ToList();

不要这样发送

var doubleFilter = 0.35d;

而不是像

那样发送
decimal doubleFilter = 0.35;

这将解决你的问题

相关内容

  • 没有找到相关文章

最新更新