通过 mongodb 嵌套对象的 c# 驱动程序防止 id 到 _id 序列化

Preventing id to _id serialization by mongodb c# driver for nested objects

我正在使用 C# mongodb 驱动程序来更新 mongodb 中的记录。下面的代码对我来说工作正常,但它会自动将所有出现的“id”转换为“_id”。

var client = GetMongoClient();
var collection1 = GetMongoCollection("collection1");
var collection2 = GetMongoCollection("collection2");

using (var session = await client.StartSessionAsync())
{
     session.StartTransaction();

    try
    {
        var filter = Builders<BsonDocument>.Filter.Eq("_id", projectInfo._Id);

        BsonDocument projectInfoBD = projectInfo.ToBsonDocument();
        var recordAfterUpdate = await collection1.ReplaceOneAsync(session, filter, projectInfoBD);
        
        ......
    }
    catch (Exception ex)
    {
        await session.AbortTransactionAsync();
        return false;
    }
}

我的 C# 类

public class ProjectInfo
{
    public string _Id { get; set; } //This is primary key which unique for project info
    public ProjectBasicDetail BasicDetails { get; set; }
}

public class ProjectBasicDetail
{
    public string Name { get; set; }
    public string Description { get; set; }
    public Option Status { get; set; }
    public TextOption CreatedBy { get; set; }
}

public class TextOption
{
    public string Id { get; set; } //don't want to convert to "_id"
    public string Name { get; set; }
}

public class Option
{
    public int Id { get; set; } //don't want to convert to "_id"
    public string Name { get; set; }
}

更新记录后,我希望更新后的记录看起来像这样

{
  "_id": "kjsldfkjlsdkfjsd",
  "basicDetails": {
    "name": "test name",
    "description": "test desc",
    "status": {
      "id": 11,
      "name": "processing"
    },
    "createdBy": {
      "id": "123",
      "name": "some user"
    }
  }
}

但它保存如下。它将所有出现的“id”转换为我不想要的“_id”

{
  "_id": "kjsldfkjlsdkfjsd", //This is ok
  "basicDetails": {
    "name": "test name",
    "description": "test desc",
    "status": {
      "_id": 11, //This should be "id"
      "name": "processing"
    },
    "createdBy": {
      "_id": "123",  //This should be "id"
      "name": "some user"
    }
  }
}

提前致谢...

属性 带有 Id 的名称被锁定以重命名为 Mongo 侧的 _id

你有2个选项。在 C# 端将其称为其他名称,例如 IdStr>

public class TextOption
{
    [BsonElement("id")]
    public string IdStr { get; set; } //don't want to convert to "_id"
    public string Name { get; set; }
}

public class Option
{
    [BsonElement("id")]
    public int IdStr { get; set; } //don't want to convert to "_id"
    public string Name { get; set; }
}

或调整基本映射>

var client = new MongoClient();
var database = client.GetDatabase("test");
var collection = database.GetCollection<ProjectInfo>("projects");
BsonClassMap.RegisterClassMap<TextOption>(cm =>
{
    cm.AutoMap();
    cm.UnmapProperty(c => c.Id);
    cm.MapMember(c => c.Id)
        .SetElementName("id")
        .SetOrder(0) //specific to your needs
        .SetIsRequired(true); // again specific to your needs
});
BsonClassMap.RegisterClassMap<Option>(cm =>
{
    cm.AutoMap();
    cm.UnmapProperty(c => c.Id);
    cm.MapMember(c => c.Id)
        .SetElementName("id")
        .SetOrder(0) //specific to your needs
        .SetIsRequired(true); // again specific to your needs
});
using (var session = await client.StartSessionAsync())
{
    await collection.InsertOneAsync(session,
        new ProjectInfo
        {
            _Id = "604b5fa389ff6887d1b91a91",
            BasicDetails = new ProjectBasicDetail
            {
                CreatedBy = new TextOption { Id = "604b5fa389ff6887d1b91a93", Name = "a" },
                Description = "b",
                Name = "c",
                Status = new Option { Id = 123, Name = "status name" }
            }
        });
}

也将 [BsonId] 添加到您的 ProjectInfo class,这样它就不会重复,并且具有 string 表示>

public class ProjectInfo
{
    [BsonId]
    public string _Id { get; set; } //This is primary key which unique for project info
    public ProjectBasicDetail BasicDetails { get; set; }
}

我认为您可以通过将 [BsonNoId] 属性添加到 class 来轻松实现此目的,如下所示:

[BsonNoId]
public class TextOption
{
    public string Id { get; set; } //don't want to convert to "_id"
    public string Name { get; set; }
}

[BsonNoId]
public class Option
{
    public int Id { get; set; } //don't want to convert to "_id"
    public string Name { get; set; }
}

这将导致不采用 属性 命名 Id 或 id 的默认值。 希望这可以帮助! ;)