2016-12-07 62 views
1

我有以下POCO類:MongoDb.Driver 2.4 deserilization數據類型改變

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

的對象存儲在MongoDB的收藏。該數據在生成的BSON正確的數據類型:

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

當我嘗試查詢集合:

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

我得到指示property2錯誤不能被反序列化: 不能反序列化'字符串'從BsonType'Int64'

我想反序列化從數據庫中的bson文檔的字符串值到我的對象上的字符串值。

爲什麼BsonSerializer嘗試將其轉換爲十進制?在這種情況下,該值恰巧是數字,但該字段在類中定義爲字符串,因爲該值通常是字母數字。

我在VS2013中使用MongoDb.Driver v2.4軟件包。

+0

字段'property2'中的集合'MyClass'包含類型爲int64的值。您可以直接在Mongo控制檯中使用javascript更新數據類型。我認爲c#驅動程序不支持相同的功能。 – rnofenko

回答

0

對於Mongo屬性類型更改,您需要爲該屬性編寫自己的序列化程序。

這是原始對象,您已將這些對象中的幾個保存到Mongo中。

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

    public string LastName { get; set; } 

    public int TestingObjectType { get; set; } 
} 

現在,我們需要的TestObjectType從int更改爲字符串

這是我們的新類

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

    public string LastName { get; set; } 

    public string TestingObjectType { get; set; } 
} 

然後,您將得到

不能反序列化來自BsonType'Int64'的'String'

你需要的是一個序列化器來處理你的轉換。

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

關鍵部分是Deserialize方法。只有當類型是int32時,才需要運行轉換邏輯。如果類型是其他任何東西,我們將假定它已經是一個字符串並返回該值。

Serialize只是WriteString out以及任何更新或保存的文檔將具有新值作爲字符串。

現在,你只需要更新你的對象,告訴物業使用您的串行

你蒙戈閱讀
public class TestingObject 
{ 
    public string FirstName { get; set; } 

    public string LastName { get; set; } 

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

下一次,你不應該得到的錯誤。