繁体   English   中英

MongoDB C# 驱动器:压平 object

[英]MongoDB C# Driver: flatten object

想象一下,我有一个像这样的 class 结构

class Aggregate
{
    string Id {get;set;}
    Parameters Parameters {get;set;}
}

class Parameters
{
    List<string> Values {get;set;}
    // logic based on Values
}

现在我想让 mongo 像这样存储它

{
    "_id": "...",
    "parameters": ["param A", "param B"]
}

如何使用BsonClassMap.RegisterClassMap对其进行配置?

我忽略了您的 class 的成员目前是私有的这一事实,因为这意味着您无法从 class 中读取任何内容。 所以让我们把它们公开

    class Aggregate
    {
        public string Id { get; set; }
        public Parameters Parameters { get; set; }
    }

    class Parameters
    {
        public List<string> Values { get; set; }
    }

所以现在我们需要一个自定义序列化程序来处理 object,然后还读回扁平化的文档。

下面只是一个将序列化Parameters委托给BsonArraySerializer的示例。

public class ParametersSerializer : IBsonSerializer
{
    private readonly BsonArraySerializer _bsonArraySerializer;

    public ParametersSerializer()
    {
        _bsonArraySerializer = new BsonArraySerializer();
    }
    public object Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
    {
        var bsonArray = _bsonArraySerializer.Deserialize(context, args);

        var netList = BsonTypeMapper.MapToDotNetValue(bsonArray, new BsonTypeMapperOptions()
        {
            MapBsonArrayTo = typeof(List<string>)
        }) as List<string>;
        return new Parameters
        {
            Values = netList 
        };
    }

    public void Serialize(BsonSerializationContext context, BsonSerializationArgs args, object value)
    {
        var typed = (Parameters) value;
        var bsonArray = new BsonArray(typed.Values);

        _bsonArraySerializer.Serialize(context, args, bsonArray);
    }

    public Type ValueType { get; } = typeof(Parameters);
}

现在我们有了这个,我们可以向我们的 class 添加一个属性来告诉 Mongo 驱动程序使用它。

class Aggregate
{
    public string Id { get; set; }

    [BsonSerializer(typeof(ParametersSerializer))]
    public Parameters Parameters { get; set; }
}

现在,当我们向 mongo 写入和读取文档时:

var pack = new ConventionPack();
pack.Add(new CamelCaseElementNameConvention());

ConventionRegistry.Register(
    "My Custom Conventions",
    pack,
    t => t == typeof(Aggregate) || t == typeof(Parameters));

var client = new MongoClient();
var database = client.GetDatabase("test");
var collection = database.GetCollection<Aggregate>("test");
await database.DropCollectionAsync(collection.CollectionNamespace.CollectionName);

await collection.InsertOneAsync(new Aggregate{Id = "...", Parameters = new Parameters{Values = {"1", "2"}}});
var all = await (await collection.FindAsync(Builders<Aggregate>.Filter.Empty)).ToListAsync();

我们将在 MongoDB 集合中获得以下保存:

> db.test.find()
{ "_id" : "...", "parameters" : [ "1", "2" ] }

另请注意,我们也在使用驼峰式案例的自定义约定来处理创建驼峰式案例属性。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM