Search code examples
c#databasemongodbidentitymongodb-.net-driver

Auto generate objects Id mongo db c#


I learn mongodb with C#, I want to create a record with a list of entities but the child entities didn't generate his object id.

Here's my code:

public class Curso
{
    [BsonId]
    public ObjectId _id { get; set; }

    [BsonElement("descripcion")]
    public string descripcion { get; set; }

    [BsonElement("horas")]
    public int horas { get; set; }

    [BsonElement("alumnos")]
    public IEnumerable<Alumno> alumnos { get; set; }

    public Curso()
    {

    }
}

Alumno entity:

public class Alumno
{
    [BsonId]
    public ObjectId _id { get; set; }

    [BsonElement("name")]
    public string name { get; set; }

    [BsonElement("age")]
    public int age { get; set; }
}

I insert a new course, the auto generate id Curso is worked but the Alumno id didn't generate and is set to "000000000000000000000000" instead.

    public Curso create(Curso curso)
    {
        db.GetCollection<Curso>("curso").Save(curso);
        return curso;
    }

RESULT:

{ "_id" : ObjectId("5a766ec765583a0f90bc0edf"), "descripcion" : "JAVA + JPA", "horas" : 200, "alumnos" : [ { "_id" : ObjectId("000000000000000000000000"), "name" : "Catalina Castillo", "age" : 22 }, { "_id" : ObjectId("000000000000000000000000"), "name" : "Marcia Pardo", "age" : 45 }, { "_id" : ObjectId("000000000000000000000000"), "name" : "Will Smith", "age" : 24 } ] }

Solution

  • Each MongoDB document should have _id field with unique value. That's why, when you pass Curso document with zero _id, MongoDB generates it for you.

    However that't not the case for embedded documents. For MongoDB, _id field in embedded document is just an ordinary field as age or name. That's why MongDB does not bother itself for filling _id of embedded documents and saves them as you pass, i.e. zero-filled.

    So you should generate values for Alumno._id by yourself. You could do it either in Alumno constructor or before inserting document in the database:

    public class Alumno
    {
        [BsonId]
        public ObjectId _id { get; set; }
    
        [BsonElement("name")]
        public string name { get; set; }
    
        [BsonElement("age")]
        public int age { get; set; }
    
        public Alumno()
        {
            _id = ObjectId.GenerateNewId();
        }
    }