Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

426
Views
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...

over 4 years ago · Santiago Trujillo
2 answers
Answer question

0

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; }
}
over 4 years ago · Santiago Trujillo Report

0

I think you can quite easily achieve this by adding the [BsonNoId] attribute to the class like so:

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

This will cause to NOT assume the default for the property named Id or id. Hope this helps! ;)

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!