首页 > 解决方案 > 如何使用 c# 在骆驼案例中将文档保存在 mongo 中?

问题描述

如何在骆驼案中将文件保存在 mongo 中?现在我试图保存这个:

  "parent_template_id": "5aa7822ba6adf805741c5722",
  "type": "Mutable",
  "subject": {
    "workspace_id": "5-DKC0PV8U",
    "additional_data": {
      "boardId": "149018",
    }

但是 boardId 转换为 db 中的 board_id (蛇形案例)。这是我在 c# 中的领域:

[BsonElement("additional_data")]
[BsonIgnoreIfNull]
public Dictionary<string, string> AdditionalData { get; set; }

标签: c#mongodb

解决方案


您需要注册一个新的序列化程序来处理您的 senario,谢天谢地,这个库是非常可扩展的,因此您只需要在需要扩展它的地方编写几个部分。

因此,首先您需要创建一个Serializer以将您的字符串键写为下划线大小写:

public class UnderscoreCaseStringSerializer : StringSerializer
{
    public override void Serialize(BsonSerializationContext context, BsonSerializationArgs args, string value)
    {
        value = string.Concat(value.Select((x, i) => i > 0 && char.IsUpper(x) ? "_" + x.ToString() : x.ToString())).ToLower();

        base.Serialize(context, args, value);
    }
}

现在我们有了一个可以使用的序列化器,我们可以在 bson 序列化器注册表中注册一个新的字典序列化器,我们的新序列化UnderscoreCaseStringSerializer器用于序列化密钥:

var customSerializer =
    new DictionaryInterfaceImplementerSerializer<Dictionary<string, string>>
        (DictionaryRepresentation.Document, new UnderscoreCaseStringSerializer(), new ObjectSerializer());

BsonSerializer.RegisterSerializer(customSerializer);

就是这样……

internal class MyDocument
{
    public ObjectId Id { get; set; }

    public string Name { get; set; }

    public Dictionary<string, string> AdditionalData { get; set; }
}

var collection = new MongoClient().GetDatabase("test").GetCollection<MyDocument>("docs");

var myDocument = new MyDocument
{
    Name = "test",
    AdditionalData = new Dictionary<string, string>
    {
        ["boardId"] = "149018"
    }
};

collection.InsertOne(myDocument);

// { "_id" : ObjectId("5b74093fbbbca64ba8ce9d0e"), "name" : "test", "additional_data" : { "board_id" : "149018" } }

您可能还想考虑使用 aConventionPack来处理字段名称下划线的约定,这只是意味着您不需要在类中乱扔BsonElement属性,它只会按约定工作。

public class UnderscoreCaseElementNameConvention : ConventionBase, IMemberMapConvention
{
    public void Apply(BsonMemberMap memberMap)
    {
        string name = memberMap.MemberName;
        name = string.Concat(name.Select((x, i) => i > 0 && char.IsUpper(x) ? "_" + x.ToString() : x.ToString())).ToLower();
        memberMap.SetElementName(name);
    }
}

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

ConventionRegistry.Register(
    "My Custom Conventions",
    pack,
    t => true);

推荐阅读