OData 4 客户端和带浮点数的过滤器
OData 4 Clients and filters with floats
我们正在使用 OData 4 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 方法并且必须构建我们的过滤器 "manually" 而不是使用 LINQ?
不要像
那样发送
var doubleFilter = 0.35d;
改为像
一样发送
decimal doubleFilter = 0.35;
这将解决您的问题
Entities?$filter=DoubleProperty eq 0.35
实际上是一个预期的表达式,如果你看一下 OData protocal 5.1.1.6.1 Primitive Literals
原始文字可以作为键 属性 值出现在资源路径中,也可以出现在查询部分,例如,作为 $filter 表达式中的操作数。它们根据 [OData-ABNF].
中的 primitiveLiteral 规则表示
和OData-ABNF定义PrimitiveLiteral
如下:
;在网址中
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();
我们正在使用 OData 4 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 方法并且必须构建我们的过滤器 "manually" 而不是使用 LINQ?
不要像
那样发送var doubleFilter = 0.35d;
改为像
一样发送decimal doubleFilter = 0.35;
这将解决您的问题
Entities?$filter=DoubleProperty eq 0.35
实际上是一个预期的表达式,如果你看一下 OData protocal 5.1.1.6.1 Primitive Literals
原始文字可以作为键 属性 值出现在资源路径中,也可以出现在查询部分,例如,作为 $filter 表达式中的操作数。它们根据 [OData-ABNF].
中的 primitiveLiteral 规则表示和OData-ABNF定义PrimitiveLiteral
如下:
;在网址中
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();