【问题标题】:Preventing id to _id serialization by mongodb c# driver for nested objectsmongodb c#驱动程序防止id到_id序列化嵌套对象
【发布时间】:2021-03-15 17:39:03
【问题描述】:

我正在使用 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"
    }
  }
}

提前谢谢...

【问题讨论】:

    标签: c# mongodb serialization deserialization mongodb-.net-driver


    【解决方案1】:

    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 类中,这样它就不会重复,并且具有string 表示>

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

    【讨论】:

      【解决方案2】:

      我认为你可以很容易地通过向类添加 [BsonNoId] 属性来实现这一点,如下所示:

      [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 的属性的默认值。 希望这可以帮助! ;)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-05-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-12-09
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多