繁体   English   中英

如何使用 c# 为 Mongodb 中的子文档创建 ID

[英]How to create ids for subdocuments in Mongodb with c#

我正在尝试为 mongodb 中的子文档自动创建 ID。

我有以下课程:

public class Test
{
    public string Id {get;set;}
    public List<SubTest> SubTestList{get;set;}

    public Test()
    {
        SubTestList = new List<SubTest>();
    }
}

public class SubTest
{
    public string Id {get;set;}
    public string Name {get;set;}
}

另一个将用于存储在 MongoDB 中的 Dll 是这样的(出于解耦的原因,它有一个自己的 dll):

public class TestMongo : Test
{
    static TestMongo()
    {
        //using this instead of attributes above every needed property. will avoid dependencies to mongodb.
        BsonClassMap.RegisterClassMap<Test>(cm =>
        {
            cm.AutoMap();

            //register property "Id" to be the mongodb.
            cm.SetIdMember(cm.GetMemberMap(c => c.Id).SetRepresentation(BsonType.ObjectId));

            //Will generate an Id and set the Id-Property which is a string in this class.
            cm.IdMemberMap.SetIdGenerator(StringObjectIdGenerator.Instance);
        });
    }
}

我以编程方式将属性添加到属性,以确保在使用测试类时不依赖于 Mongo。

现在我需要为每个创建的子测试元素自动创建一个 Id。 我试图在 TestMongo-Constructor 中添加另一个 map 但它没有用:

...
BsonClassMap.RegisterClassMap<SubTest>(cm =>
{
    cm.AutoMap();

    //register property "Id" to be the mongodb.
    cm.SetIdMember(cm.GetMemberMap(c => c.Id).SetRepresentation(BsonType.ObjectId));

    //Will generate an Id and set the Id-Property which is a string in this class.
    cm.IdMemberMap.SetIdGenerator(StringObjectIdGenerator.Instance);
 });

当然,我可以在将其写入 mongo 之前遍历所有 SubTest-Elements,但我更愿意让 c#-driver 为我做这件事。

有什么办法可以做到这一点?

这种方式将自定义对象序列化程序用于mongo:

1-编写串行器:

public class TestSerialzer : IBsonSerializer
{
    public object Deserialize(BsonReader bsonReader, Type nominalType, IBsonSerializationOptions options)
    {
        return BsonSerializer.Deserialize<Test>(bsonReader);
    }

    public object Deserialize(BsonReader bsonReader, Type nominalType, Type actualType, IBsonSerializationOptions options)
    {
        throw new NotImplementedException();
    }

    public IBsonSerializationOptions GetDefaultSerializationOptions()
    {
        throw new NotImplementedException();
    }

    public void Serialize(BsonWriter bsonWriter, Type nominalType, object value, IBsonSerializationOptions options)
    {            
        var test = (Test)value;
        bsonWriter.WriteStartDocument();

        if (string.IsNullOrEmpty(test.Id)) test.Id = ObjectId.GenerateNewId().ToString();

        bsonWriter.WriteString("_id", test.Id);

        foreach (var nestedObj in test.SubTestList)
        {
            if (string.IsNullOrEmpty(nestedObj.Id)) nestedObj.Id = ObjectId.GenerateNewId().ToString();
        }

        bsonWriter.WriteStartArray("SubTestList");
        BsonSerializer.Serialize(bsonWriter, test.SubTestList);

        bsonWriter.WriteEndArray();
        bsonWriter.WriteEndDocument();
    }
}

在应用启动时注册序列化程序:

BsonSerializer.RegisterSerializer(typeof(Test), new TestSerialzer());

对于以下测试对象:

var test = new Test
{
    SubTestList = new List<SubTest>
    {
      new SubTest
      {
          Name = "Name1",
      },
      new SubTest
      {
        Name  = "Name2",
      },
    },
};
collection.Insert(test);

您将拥有:

{
    "_id" : "54ad5b25e8b07a214c390ccf",
    "SubTestList" : [ 
        [ 
            {
                "_id" : "54ad5b25e8b07a214c390cd0",
                "Name" : "Name1"
            }, 
            {
                "_id" : "54ad5b25e8b07a214c390cd1",
                "Name" : "Name2"
            }
        ]
    ]
}

一个简单的解决方案:

using MongoDB.Bson;

myNewSubdocument.Id = ObjectId.GenerateNewId().ToString();

暂无
暂无

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

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