[英]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.