I have a problem while upserting to mongo db using the official C# driver.
public abstract class AggregateRoot
{
/// <summary>
/// All mongoDb documents must have an id, we specify it here
/// </summary>
protected AggregateRoot()
{
Id = ObjectId.GenerateNewId();
}
[BsonId]
public ObjectId Id { get; set; }
}
My entities already have the id-s but I had to create the mongo specific Id for it to work, as all the documents in a collection should have one. Now then I receive a new entity in my system a new Mongo Id is generated and I get the mongo cannot change _id of a document old exception. Is there some work-around?
Let me describe the design a bit. All the entities which would be stored as documents were inheriting from AggregateRoot which had the id generation in it. Every sub-document had its id generated automatically and I had no problem with this. The id in AggregateRoot was introduced to correct the problem when retrieving data from MongoCollection to List and the generation was introduced so the id-s are different. Now we can move that id generation to save methods because the new entity for update had a new id generation. But it would mean that every dev on the team must not forget generating id-s in repository which is risky. It would be nicer just to ignore the id than mapping from mongo if it is possible and not to have AggregateRoot class at all
Looks like you might be explicitly setting the Id
value for both inserts and updates. That's fine for inserts, all new objects need an _id
value, however for updates you're not allowed to change the value of _id
on an existing document after it's created.
Try not setting the Id
value at all. If you don't specify a value before inserting, the driver uses built-in IdGenerator
classes to generate a new _id value, so if it's an ObjectId type it'll use the ObjectIdGenerator
. Then both your inserts and updates work fine.