简体   繁体   中英

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

I am using C# mongodb driver to update record in mongodb. Below code works fine for me but it's automatically converting all occurrences of "id" to "_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;
    }
}

My C# classes

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; }
}

After updating record I am expecting updated record to look like this

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

but it saved like below one. It's converting all occurrences of "id" to "_id" which I don't want

{
  "_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"
    }
  }
}

Thanks in advance...

Property name with Id is locked to rename to _id on Mongo side.

You have 2 options. Call it something other on C# side, like 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; }
}

Or tweak with the base mapping>

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" }
            }
        });
}

also add the [BsonId] to your ProjectInfo class, so it's not duplicated, and have string representation>

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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