Working with _id in .Net

I am trying to add data to MongoDB from a .net application. My question deals with the _id field in mongo.

In my user collection I manually added some users. Those users have an _id field of type string.

_id: “60ff64082fe05c5723b9ab4e”

The users that are added from the application have an _id of type ObjectID

_id: ObjectId(“6128201eb97cc576468e6fe7”)

Is this the wrong way to do this? Do I need to leave the _id alone and define another Id field or can I use this for a unique identifier?

2 Likes

Update:

I was looking at how this happened and I need some clarification. In the .Net project, in the classes (user, store, product) the id field has the following entered:

 [BsonElement("_id")]
        [JsonProperty("_id")]
        [BsonId]
        [BsonRepresentation(BsonType.ObjectId)]
        public string Id { get; set; }

Because of this I thought that the _id : “60ff64082fe05c5723b9ab4e” needed to be in Mongo as a string since it is a string in the VS project.

Since it is a string, it errors out when trying to use the _id field. (The system says it needs it to be an Object) is there any documentation on how to effectively use this field in your program? I like the field due to its high cardinality.

Dave

Hi, David,

Documents in MongoDB must have an _id member, which uniquely identifies the document within a collection. The .NET/C# driver automatically adds an _id member if you don’t assign one explicitly. The driver automatically maps the Id property of a class to the _id field in the database. You can override this with class mapping attributes or code configuration if desired.

When a new document is inserted into a collection, it will use the value of the Id property if it is assigned. If not, it will generate a new Id using the configured IIdGenerator. The defaults work well for most users. If the Id property is an ObjectId, the ObjectIdGenerator will be used. If a string, then the StringObjectIdGenerator will be used. There are other generators and you can find additional details in our documentation on The Id Member.

For most applications, the default conventions work well without additional configuration. I would recommend starting with the following and let the defaults do their magic:

public class Animal
{
    public ObjectId Id { get; set; }
    // other properties and code
}

You can find more information on mapping classes in Mapping.

Hope that helps.

Sincerely,
James

2 Likes

Thanks… I just finished the .net course M220… I noticed in the classes they configured it like this.

 public class User
    {
        [BsonElement("_id")]
        [JsonProperty("_id")]
        [BsonId]
        [BsonRepresentation(BsonType.ObjectId)]
        public string Id { get; set; }

Is this the proper way to set up the _id as a string?
If you are going to use the _Id as a string, you need the elements above it or is this an old way of identifying it that has sense been programmed onto the C# driver

Respectfully,

Dave

1 Like

If [BsonId] isn’t specified, we look for an Id property to represent the database’s _id field. The only time I would apply [BsonId] is if I wanted to use another property name for my _id field such as KeyId or DocumentId or whatever made sense for my business model. The vast majority of the time, I simply use an unannotated Id property.

The [BsonElement] and [JsonProperty] annotations are redundant. They’re added as examples of how you can customize the serialization to BSON and JSON respectively if needed. Most of the time this is not needed and I would leave them off.

Regarding the [BsonRepresentation], that allows you to map how you represent the _id property in your C# object model versus how it is represented in the database. MongoDB requires every document to have a unique _id field, but does not require any specific data type. By default MongoDB uses ObjectId for _id, but you can use a string, an integer, or even a subdocument. The only requirement is that _id is unique within a collection. In my own applications, I will define public ObjectId Id { get; set; } as we have an IIdGenerator for ObjectIds that ensures uniqueness and monotonicity. A monotonically increasing generator ensures that when generating a sequence of values, the next one is always greater than the last one. This is important for efficient indexing in databases and can affect insert performance if the generator is not monotonically increasing. (The default algorithm for generating GUIDs is not monotonically increasing, which is why the GuidComb generation algorithm was devised.)

That was a long way to say use an unadorned public ObjectId Id { get; set; } unless you’ve got a defined need to do something different. Then you can customize as needed using the attributes in the example.

Sincerely,
James

3 Likes

Thank you very much for your post. I cannot say I understand it totally ( I am a hands on learner) but I now know what those validation statements in VS are used for.

1 Like

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.