MongoDB BsonSerializer.Deserialize 和 F#

标签 mongodb f# bson

以下代码段似乎可以正确序列化记录,但反序列化会将字段设置为其默认值。

open MongoDB.Bson
open MongoDB.Bson.Serialization
open System

module BsonIssue = 

    type MyData =
        { 
            Id : ObjectId
            Time : DateTime
        }

    let serialize(data : MyData) =
        let doc = BsonDocument()
        BsonSerializer.Serialize<MyData>(new IO.BsonDocumentWriter(doc), data)
        doc

    let deserialize(doc : BsonDocument) =
        printfn "Attempting to deserialize %A" doc
        BsonSerializer.Deserialize<MyData>(doc)

    let data = { Id = ObjectId.GenerateNewId(); Time = DateTime.Now }
    printfn "The data: %A" data
    let serialized = serialize data
    printfn "After serialization: %A" serialized
    let deserialized = deserialize serialized
    printfn "After deserialization: %A" deserialized

这是一个输出示例:

数据:

{Id = 55de887754893731fceeef58;
 Time = 8/26/2015 11:48:07 PM;}
After serialization: seq [_t=MyData; _id=55de887754893731fceeef58; Time=2015-08-27T03:48:07.836Z]
Attempting to deserialize seq [_t=MyData; _id=55de887754893731fceeef58; Time=2015-08-27T03:48:07.836Z]
After deserialization: {Id = 000000000000000000000000;
 Time = 1/1/0001 12:00:00 AM;}

提前致谢。

最佳答案

添加 [<CLIMutable>] 记录在案:

[<CLIMutable>]
type MyData =
    { 
        Id : ObjectId
        Time : DateTime
    }

FSI session :

> let data = { Id = ObjectId.GenerateNewId(); Time = DateTime.Now };;    
val data : MyData = {Id = 55dea10c4bd766216837843d;
                     Time = 27.08.2015 07:33:00;}

> let serialized = serialize data;;    
val serialized : BsonDocument

> let deserialized = deserialize serialized;;    
val deserialized : MyData = {Id = 55dea10c4bd766216837843d;
                             Time = 27.08.2015 05:33:00;}

但是,请注意记录没有正确往返,因为 Time值不同 - 至少在我的机器上。两个小时的时差似乎可以解释为我目前比 UTC 早两个小时,所以我的猜测是 BSON (de)serializer 解释所有 DateTime值作为 UTC 值。

您应该使用 DateTimeOffset 来解决这个问题。而是:

[<CLIMutable>]
type MyData =
    { 
        Id : ObjectId
        Time : DateTimeOffset
    }

FSI session :

> let data = { Id = ObjectId.GenerateNewId(); Time = DateTimeOffset.Now };;    
val data : MyData = {Id = 55dea3534bd766216837843f;
                     Time = 27.08.2015 07:42:43 +02:00;}

> let serialized = serialize data;;    
val serialized : BsonDocument

> let deserialized = deserialize serialized;;    
val deserialized : MyData = {Id = 55dea3534bd766216837843f;
                             Time = 27.08.2015 07:42:43 +02:00;}

> data = deserialized;;
val it : bool = true

关于MongoDB BsonSerializer.Deserialize 和 F#,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32240388/

相关文章:

ruby - Mongoid 给出未初始化的常量 Mongo

MongoDB:删除多个对象内的项目

c# - 从 F# 中的 map 中删除所有内容

mongodb - 在不使用 GridFS 的情况下将图像存储在 MongoDB 的文档中

c# - 如何将 Observable Collection 上的空数据解析为数据网格绑定(bind)?

java - 如何使用 Spring Data Mongo DB 对类进行建模来存储具有不同长度字段和类型的嵌套 JSON 文档

php - 类型为 SINGLE_COLLECTION 架构的 ODM 继承文档创建错误

node.js - 根据属性过滤 mongodb 文档并链接结果

f# - 为什么这个计算表达式构建器在我的 for 循环中期望 "unit"?

f# - 为 F# 中的可区分联合自动生成谓词和访问器