JsonProvider <...> .Root没有为空作为适当的值

问题描述:

我想查询解析Json的结果,如果我找不到我想做其他事情。JsonProvider <...> .Root没有为空作为适当的值

[ 
    { 
    "orderId": 136, 
    "quantity": 5, 
    "price": 3.75 
    }, 
    { 
    "orderId": 129, 
    "quantity": 9, 
    "price": 3.55 
    }, 
    { 
    "orderId": 113, 
    "quantity": 11, 
    "price": 3.75 
    } 
] 

我的代码是这样的:

type OrdersProvider = JsonProvider<"Orders.json"> 
let orders = OrdersProvider.GetSamples() 

let test id = 
    let res = query{ 
        for i in orders do 
         where (i.OrderId = id) 
         select i 
         headOrDefault 
       } 

    if isNull(res) 
     then NOT_FOUND("") 
     else OK(res.JsonValue.ToString()) 
    ) 

不过我正在编译器错误 “JsonProvider < ...>根没有null作为应有的价值。”这是有道理的,除非我还想在id不在文件中的情况下进行处理。我想我可以改变头或默认头和陷阱的例外,但不知道是否有更好的东西。

更新#1: 继评论的链接之一,我能够与

if obj.ReferenceEquals(res,null) 
     then NOT_FOUND("") 
     else OK(res.JsonValue.ToString()) 
    ) 

更新#2闪避: 虽然提到代码的作品,但仍然感觉不自然的语言。接受的答案看起来更自然。

+0

看到这个答案:https://*.com/a/11696947/679898,这是一个更普遍的问题,但解决方案应该适用。 – scrwtp

+0

可能重复的[类型没有null作为适当的值](https://*.com/questions/11696484/type-does-not-have-null-as-a-proper-value) – scrwtp

+0

@scrwtp它是不是https://*.com/questions/11696484/type-does-not-have-null-as-a-proper-value的副本,除非有方法将属性AllowNullLiteral应用于OrdersProvider.Root。但是另一个链接帮助。我能够摆脱obj.ReferenceEquals – AlexanderM

我觉得headOrDefault操作是专为使用LINQ到SQL,这就是为什么它在默认情况下返回null兼容性 - 这是不是你通常要在很乖F#代码的东西,所以使用它的方式你的查询不是一个好主意。

幸运的是,headOrDefault将与F#选项类型工作 - 如果你从select子句返回Some然后headOrDefault回报None当值不可用:

let res = 
    query { 
    for i in orders do 
    where (i.OrderId = id) 
    select (Some i) 
    headOrDefault } 

现在,您可以处理与模式匹配的失踪案:

match res with 
| None -> NOT_FOUND("") 
| Some order -> OK(order.JsonValue.ToString())