2015-08-27 16 views
5

Il seguente frammento sembra serializzare correttamente il record, ma la deserializzazione imposta i campi sui valori predefiniti.MongoDB BsonSerializer.Deserialize e F #

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 

Ecco un esempio dell'output:

I dati:

{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;} 

Grazie in anticipo.

risposta

5

Aggiungi [<CLIMutable>] al record:

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

FSI sessione:

> 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;} 

Do, tuttavia, notare che il record non lo fa andata e ritorno correttamente, perché i valori differiscono Time - Almeno sulla mia macchina. La differenza di tempo di due ore sembra spiegabile dal fatto che attualmente sono due ore avanti rispetto a UTC, quindi suppongo che il serializzatore BSON (de) interpreti tutti i valori DateTime come valori UTC.

Si dovrebbe risolvere questo problema utilizzando DateTimeOffset invece:

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

FSI sessione:

> 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 
+0

Grazie molto. Divertente perché ho scelto di usare DateTime solo per fare un esempio. Buona presa su quello pure. –