2016-12-07 3 views
1

ich folgende POCO-Klasse haben:MongoDb.Driver 2.4 deserilization Datentyp zu ändern

class MyClass { 
    public Objectid _id {get;set;} 
    public string property1 {get;set;} 
    public string property2 {get;set;} 
    public int property3 {get;set;} 
} 

Das Objekt in der MongoDB Sammlung gespeichert. Die Daten haben die richtigen Datentypen in der resultierenden BSON:

property1: "SomeString" 
property2: "12345" 
property3: 98765 

Wenn ich die Sammlung abzufragen versuchen:

var items = db.GetCollection<MyClass>("MyClass").AsQueryable().Select(x => x.property1 == "SomeString").ToList(); 

Ich erhalte eine Fehlermeldung, dass property2 anzeigt nicht deserialisiert werden: Kann kein deserialisieren 'String' von BsonType 'Int64'

Ich versuche, einen String-Wert aus dem Bson-Dokument in der DB zu einem String-Wert auf meinem Objekt zu deserialisieren.

Warum versucht der BsonSerializer, es in Dezimal zu konvertieren? In diesem Fall ist der Wert numerisch, das Feld ist jedoch in der Klasse als Zeichenfolge definiert, da der Wert normalerweise alphanumerisch ist.

Ich verwende das MongoDb.Driver v2.4-Paket in VS2013.

+0

Sammlung 'MyClass' im Feld 'property2' enthält Werte vom Typ int64. Sie können den Datentyp mit Javascript direkt in der Mongo-Konsole aktualisieren. Ich denke, C# -Treiber unterstützt nicht die gleiche Funktion. – rnofenko

Antwort

0

Für eine Eigenschaftsänderung Mongo müssen Sie Ihren eigenen Serializer für diese Eigenschaft schreiben.

Dies ist das ursprüngliche Objekt, und Sie haben mehrere dieser Objekte in Mongo gespeichert.

public class TestingObject 
{ 
    public string FirstName { get; set; } 

    public string LastName { get; set; } 

    public int TestingObjectType { get; set; } 
} 

Jetzt brauchen wir

Dies ist unsere neue Klasse

public class TestingObject 
{ 
    public string FirstName { get; set; } 

    public string LastName { get; set; } 

    public string TestingObjectType { get; set; } 
} 

die TestObjectType von einem int in eine Zeichenfolge ändern Sie dann die bekommen

Kann ein nicht deserialisieren 'String' von BsonType 'Int64'

Was Sie brauchen, ist ein Serializer, der die Konvertierung für Sie übernimmt.

public class TestingObjectTypeSerializer : IBsonSerializer 
{ 
    public Type ValueType { get; } = typeof(string); 

    public object Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args) 
    { 
     if (context.Reader.CurrentBsonType == BsonType.Int32) return GetNumberValue(context); 

     return context.Reader.ReadString(); 
    } 

    public void Serialize(BsonSerializationContext context, BsonSerializationArgs args, object value) 
    { 
     context.Writer.WriteString(value as string); 
    } 

    private static object GetNumberValue(BsonDeserializationContext context) 
    { 
     var value = context.Reader.ReadInt32(); 

     switch (value) 
     { 
      case 1: 
       return "one"; 
      case 2: 
       return "two"; 
      case 3: 
       return "three"; 
      default: 
       return "BadType"; 
     } 
    } 
} 

Der Schlüssel ist die Deserialize-Methode. Nur wenn der Typ int32 ist, möchten Sie Ihre Konvertierungslogik ausführen. Wenn der Typ ein anderes ist, nehmen wir an, dass es bereits eine Zeichenkette ist, und geben Sie diesen Wert zurück.

Die Serialize nur WriteString aus und jedes Dokument entweder aktualisiert oder gespeichert wird den neuen Wert als Zeichenfolge haben.

Jetzt müssen Sie nur noch Ihr Objekt aktualisieren, um die Immobilie zu sagen, Ihre Serializer

public class TestingObject 
{ 
    public string FirstName { get; set; } 

    public string LastName { get; set; } 

    [BsonSerializer(typeof(TestingObjectTypeSerializer))] 
    public string TestingObjectType { get; set; } 
} 

nächste Mal, wenn Sie es von Mongo lesen zu verwenden, sollten Sie nicht den Fehler.

Verwandte Themen