[CSHARP-1674] Clarify documentation for when StringObjectIdGenerator would be used Created: 22/May/16  Updated: 21/Apr/23

Status: Backlog
Project: C# Driver
Component/s: Documentation, Serialization
Affects Version/s: 2.2.4
Fix Version/s: None

Type: Task Priority: Minor - P4
Reporter: Marko Hrovatic Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: driver, neweng
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Windows 10 x64, MongoDb 3.2.6



 Description   

I am trying to follow simple steps in the C# driver Quick start but I am hitting a major road block because the driver won't create an ID for my Id public property.

If I understand the docs correctly the driver should use the StringIdGenerator to generate an ID for my

public string Id

{ get; set; }

property on my models.

I posted a question on SO about this:
http://stackoverflow.com/questions/37361002/mongodb-2-0-c-sharp-driver-not-creating-id-on-inserts

Since I posted the question I also attached [BsonId] attribute to the property if that would made any difference but it still resulted in null ID being used with InsertOne() which at the 2nd retry results in

A bulk write operation resulted in one or more errors.
E11000 duplicate key error collection: testdb.Customer index: id dup key: { : null }

(obviously).

I also tried registering a class map simply with

BsonClassMap.RegisterClassMap<Customer>();

and it still would not create a value for the Id property.



 Comments   
Comment by Robert Stam [ 28/Jun/16 ]

Hi Marko, sorry for not replying sooner but it seemed like you had already found a solution.

To clarify, the StringObjectIdGenerator is not used automatically for string _ids, unless that string is represented externally as an ObjectId.

So when inserting documents of class A the StringObjectIdGenerator is not used:

public class A
{
    public string Id;
}

because the driver has no way of knowing what type of strings might be used as _id values, and there is no particular reason to believe that the StringObjectIdGenerator would be the appropriate one to use.

However, when inserting documents of class B, the StringObjectIdGenerator would be used:

public class B
{
    [BsonRepresentation(BsonType.ObjectId)]
    public string Id;
}

Because in this class the _id is "a string represented externally as an ObjectId". In this case it is appropriate to use the StringObjectIdGenerator.

Just to be clear, in class B you are declaring you Id property as type string even though in the database the values are stored as ObjectIds. When saving a document of type B the string value is converted to an ObjectId before saving the document (and an exception would be thrown if the string value is not a valid string representation of an ObjectId).

I'm going to leave this ticket open as a task to clarify the documentation to avoid confusion about when the StringObjectIdGenerator is used.

Comment by Marko Hrovatic [ 27/Jun/16 ]

In one month no one seemed to care to take a look at this...

Comment by Marko Hrovatic [ 22/May/16 ]

Ok, finally I made this working. I had to put attribute [BsonId] set to StringObjectIdGenerator to Id properties.

[BsonId(IdGenerator = typeof(StringObjectIdGenerator))]

The docs at http://mongodb.github.io/mongo-csharp-driver/2.2/reference/bson/mapping/#id-generators are certainly misleading or not clear enough

"Some of these Id generators are used automatically for commonly used Id types:

GuidGenerator is used for a Guid
ObjectIdGenerator is used for an ObjectId
StringObjectIdGenerator is used for a string represented externally as ObjectId"

Generated at Wed Feb 07 21:40:20 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.