2015-09-08 19 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; }