Preface
I have tried several solutions which appear identical to one another. I have an issue in regards to inserting new documents into my Azure Cosmos DB. The error I am getting is a duplicate key error. What I am trying to accomplish is having Azure Cosmos DB generate the key on its own for me, instead of myself having to explicitly create the key in code.
The main concern I have with generating the key in my .Net logic is the chance of my .Net application creating duplicate keys due to it briefly going down at times which could reset its internal server clock. I do not believe this could happen in Azure, so I am hoping to take advantage of this by having it continue to generate the keys when an insert occurs.
Simple Code Sample
I am using an interface model to store my object in the Azure Database.
interface IExample
{
ObjectId Id { get; set; }
}
I also have a concrete class designed implementing this interface.
public class Example : IExample
{
public ObjectId Id { get; set; }
}
Examples with Attempted Data Annotations
I have tried using the following attributes and their combinations in both the interface and class above for the Id field.
interface IExample
{
[BsonId]
ObjectId Id { get; set; }
}
public class Example : IExample
{
[BsonId]
public ObjectId Id { get; set; }
}
interface IExample
{
[DatabaseGenerated(DatabaseGeneratedOption.Calculated)]
ObjectId Id { get; set; }
}
public class Example : IExample
{
[DatabaseGenerated(DatabaseGeneratedOption.Calculated)]
public ObjectId Id { get; set; }
}
interface IExample
{
[BsonId, DatabaseGenerated(DatabaseGeneratedOption.Calculated)]
ObjectId Id { get; set; }
}
public class Example : IExample
{
[BsonId, DatabaseGenerated(DatabaseGeneratedOption.Calculated)]
public ObjectId Id { get; set; }
}
None of these combinations appear to be telling the CosmosDB that Id should be generated by itself when I have my collection object insert the model.
Repository Example
The following is currently what I am working with when I insert a document into my collection in my repository file.
private ICosmosExampleDBContext _dbContext { get; set; }
private readonly IMongoCollection<IExample> _collection;
public ExampleRepository(ICosmosExampleDBContext dbContext, IOptions<ExampleOptions> options)
{
this._dbContext = dbContext;
this._collection = this._dbContext.GetCollection<IExample>(options.Value.Collection);
}
public void CreateExample(IExample example)
{
try
{
// A duplicate key error is created if I don't explicitly create the key here.
// E11000 is encountered without this, even with above data annotations.
example.Id = MongoDB.Bson.ObjectId.GenerateNewId();
this._collection.InsertOne(example);
}
catch(Exception e)
{
throw e;
}
}
I guess my follow up questions for this over-arching question is:
- Is it wrong for me to want to have the Cosmos DB generate my key?
- Should I keep explicitly creating the key instead of wanting CosmosDB to generate it for me?
The error I am getting is E11000 without the explicit Object ID creation.
Edit: Updated code for attempted data annotations, to show implementation of IExample.