2015-09-08 18 views
1

我想序列化Dictionary<long, VALUE>到MongoDB中的以下JSON。序列化字典<long, VALUE>到BSON文檔

{ 
    "213" : {}, 
    "63624" : {}, 
    ... 
} 

我不希望其他DictionaryRepresentation除了DictionaryRepresentation.Document.Document

我使用MongoDB的C#驅動程序(v2.0.1.27),這是不聰明的long型鍵轉換爲string,這導致一個例外。

謝謝

+0

[序列化字典到BSON時BsonSerializationException]的可能重複(http://stackoverflow.com/questions/28111846/bsonserializationexception-when-serializing-a-dictionarydatetime-t-to-bson) – i3arnon

+0

別我認爲它是一樣的,我不想'ArrayOfArrays'表示。該解決方案是否也在這裏工作? –

回答

5

可以與現有的串行做到這一點,但它需要配置少量。

假設下面的類:

public class C 
{ 
    public int Id { get; set; } 
    public Dictionary<long, long> D { get; set; } 
} 

您可以配置爲使用該序列化渴望串鑰匙串的d屬性(字典)自定義序列。該代碼是這樣的:

BsonClassMap.RegisterClassMap<C>(cm => 
{ 
    cm.AutoMap(); 
    var customDictionarySerializer = new DictionaryInterfaceImplementerSerializer<Dictionary<long, long>>(
     dictionaryRepresentation: DictionaryRepresentation.Document, 
     keySerializer: new Int64Serializer(BsonType.String), 
     valueSerializer: BsonSerializer.SerializerRegistry.GetSerializer<long>()); 
    cm.GetMemberMap(c => c.D).SetSerializer(customDictionarySerializer); 
}); 

這裏的關鍵思想是,即使鍵和值均爲多頭,我們使用了鍵和值不同的序列化。

如果我們再運行一​​個快速測試:

var document = new C { Id = 1, D = new Dictionary<long, long> { { 2, 3 } } }; 
var json = document.ToJson(); 
Console.WriteLine(json); 

我們看到,詞典按鍵現在被序列化爲字符串:

{ "_id" : 1, "D" : { "2" : NumberLong(3) } } 
1

我也摸索出另一種解決方案,希望它有助於其他人們

public class LongDictionarySerializer<K> : DictionarySerializerBase<Dictionary<long, K>> 
{ 
    public LongDictionarySerializer() : base(DictionaryRepresentation.Document) 
    { 
    } 

    protected override Dictionary<long, K> CreateInstance() 
    { 
     return new Dictionary<long, K>(); 
    } 

    public override void Serialize(BsonSerializationContext context, BsonSerializationArgs args, Dictionary<long, K> value) 
    { 
     if (value != null) 
     { 
      Dictionary<string, K> dic = value.ToDictionary(d => d.Key.ToString(), d => d.Value); 
      BsonSerializer.Serialize<Dictionary<string, K>>(context.Writer, dic); 
     } 
     else 
      BsonSerializer.Serialize<object>(context.Writer, null); 
    } 
    public override Dictionary<long, K> Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args) 
    { 
     Dictionary<string, K> dic = BsonSerializer.Deserialize<Dictionary<string, K>>(context.Reader); 
     if (dic == null) 
      return null; 

     Dictionary<long, K> ret = new Dictionary<long, K>(); 
     foreach(var pair in dic) 
     { 
      long key; 
      if (!long.TryParse(pair.Key, out key)) 
       continue; 
      ret[key] = pair.Value; 
     } 
     return ret; 
    } 
} 

此時場

[BsonElement(Fields.Markets)] 
[BsonSerializer(typeof(LongDictionarySerializer<XXX>))] 
public Dictionary<long, XXX> Markets { get; set; }