我正在尝试查询已解析的Json的结果,如果我找不到,我想做其他事情。
[
{
"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&lt; ...&gt; .Root没有null作为正确的值”。哪个是有道理的,除了我还想抓住id不在文件中的情况。我想我可以将headOrDefault更改为head并捕获异常,但想知道是否有更好的东西。
更新#1: 按照评论中的其中一个链接,我就可以逃脱
if obj.ReferenceEquals(res,null)
then NOT_FOUND("")
else OK(res.JsonValue.ToString())
)
更新#2: 虽然提到的代码有效,但仍然觉得语言不自然。接受的答案看起来更自然。
答案 0 :(得分:2)
我认为headOrDefault
操作是为了与LINQ to SQL的兼容性而设计的,这就是为什么它在默认情况下返回null
- 这不是你通常想要的表现良好的东西F#代码,所以在你的查询方式中使用它不是一个好主意。
幸运的是,headOrDefault
将使用F#选项类型 - 如果您从Some
子句返回select
,那么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())