在MongoDB中使用嵌套数组保存字典

时间:2012-11-15 11:02:47

标签: c# mongodb serialization json.net mongodb-.net-driver

以下类应由API作为Json接收并使用C#驱动程序和Web API存储在MongoDB中。 data属性是非结构化的,但是我可以将它限制为键值对,并在这些值中包含可能嵌套的数组。

public class Something
{
    [BsonId, JsonIgnore]
    public ObjectId _id { get; set; }

    public IDictionary<string, object> data { get; set; }
}

当从客户端发布json时,Json.NET正确反序列化。

将类保存到MongoDB,我在数据库中使用c#特定类型得到类似的内容:

{
    property1: 'one',
    property2: {
        _t: 'System.Collections.Generic.List`1[System.Object]'
        _v:
        [
            {}, {}, {}, ...
        ]
     }
}

基于这些来源,我将Json.NET的CustomCreationConverter整合在一起,将List嵌入到Dictionary的值中:

Apply JsonDictionaryAttributes to properties

Json.NET: Deserializing nested dictionaries

CustomCreationConverter Source Code

public class Something
{
    ...
    [JsonProperty(ItemConverterType = typeof(CustomConverter))]
    public IDictionary<string, object> data { get; set; }
}

使用此覆盖:

public class CustomConverter : CustomCreationConverter<IList<object>>
{
    public override IList<object> Create(Type objectType)
    {
        return new List<object>();
    }

    public override bool CanConvert(Type objectType)
    {
        return true; // Just to keep it simple
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        if (reader.TokenType == JsonToken.StartArray)
            return base.ReadJson(reader, objectType, existingValue, serializer);

        return serializer.Deserialize(reader);
    }
}

这实际上很好,但我仍然在MongoDB中使用c#特定类型构建。在嵌套时如何在没有类型值属性的情况下将此数据导入MongoDB?

1 个答案:

答案 0 :(得分:2)

所以我使用Dictionary<>而不是IDictionary<>没有自定义转换器,但我也使用自己的类型而不只是object。我不清楚“有用的方式”是什么意思,但你可以用BsonDictionaryOptionsAttribute注释你的成员并传入DictionaryRepresentation.DocumentDictionaryRepresentation.ArrayOfDocument来改变持久存在MongoDB的形状,如果这是什么你的意思是?

否则,对于现在的结构方式,“有用的方式”是什么意思?只要可能存在多种类型,您就可以获得"_t"鉴别器。我猜你正在看到这个,因为你正在使用IDictionary<>