M. Pipal
M. Pipal

Reputation: 734

Default ObjectId in MongoDB

I'm using MongoDB for storing data in WPF app. I've few 'model' classes, which inherits from the same base like this:

Base:

public class MongoEntityBase
{
   [BsonId]
   [BsonIgnoreIfDefault]
   public ObjectId Id { get; set; }

   public DateTime DateCreated { get; set; }
}

First data class:

public class Class1 : MongoEntityBase
{
   public string Description { get; set; }

   public decimal MaxAmount { get; set; }
}

Second data class:

public class Class2 : MongoEntityBase
{
   public string Code { get; set; }

   public string Message { get; set; }
}

I use ReplaceAsync with activated Upsert function for inserting or updating data. When I insert new Class1 entity, it's correctly stored in DB with generated ObjectId, but when I insert Class2 entity the same way, it's stored with default ObjectId (just zeros). So when I insert some second new document, it just replaces the first one, so it's not possible to have more than one document in this collection.

Do you have any idea, why it works in one case and not in other? Any advice?

Upvotes: 1

Views: 3685

Answers (1)

M. Pipal
M. Pipal

Reputation: 734

Ok, sorry for topic, I probably found the problem after two days. Because Code in first class has to be unique, I'm calling this constrution:

await _coll.ReplaceOneAsync(m => m.Code == message.Code, message, 
                     new UpdateOptions { IsUpsert = true });

In this case, I'm searching DB with 'non-Id' node and when the code couldn't be find, than Mongo create new document and replace DefaultId with generated one.

But in the second case with Class1, I don't have any unique field, so I'm calling this:

await _coll.ReplaceOneAsync(c => c.Id.Equals(code.Id), code, 
                     new UpdateOptions {IsUpsert = true});

So I 'touch' Id field and in this case Mongo probably thinks, that this is the Id I want to work with, so when some document come with DefaultId, it's stored with this DefaultId and not replaced with generated one. When second document comes with Id, it's just replaced. In this case is necessary to generate Id manually before you save document like this:

if(entity.Id == ObjectId.Empty)
   entity.Id = ObjectId.GenerateNewId();

It's not so clear by my opinion, so I hope this helps to someone.

Upvotes: 1

Related Questions