I am testing MongoDB (server v 2.6.7) with the C# driver 2.0.
When I am using the insert function InsertOneAsync
for a document with an _id
which exists I am expecting an error like the one you get from the Mongo shell:
WriteResult({
"nInserted" : 0,
"writeError" : {
"code" : 11000,
"errmsg" : "insertDocument :: caused by :: 11000 E11000 duplicate key error index: mydb.Commands.$_id_ dup key: { : 0.0 }"
}})
But the problem is that the insert with the C# driver does not throw an exception and I can not find the WriteResult
for the insert.
When I look in the database it seems nothing have happened.
So my question is what to expect from InsertOneAsync
when inserting an existing _id
?
The code in Visual Studio:
IMongoCollection<BsonDocument> commandsCollection = db.GetCollection<BsonDocument>("Commands");
var bson = new BsonDocument
{
{"_id", i.Value},
{"label", i.Key}
};
commandsCollection.InsertOneAsync(bson);
If you're doing this within an async
method, then Brduca's answer will work (and is preferrable), otherwise you can call Wait()
on the Task
returned from the InsertOneAsync
call to ensure your application stays around long enough to see the duplicate key exception:
commandsCollection.InsertOneAsync(doc).Wait();
If the insert fails because of a duplicate key, the Wait()
will throw an AggregateException
that contains a MongoWriteException
that contains the duplicate key details.
try
{
commandsCollection.InsertOneAsync(doc).Wait();
}
catch(AggregateException aggEx)
{
aggEx.Handle(x =>
{
var mwx = x as MongoWriteException;
if (mwx != null && mwx.WriteError.Category == ServerErrorCategory.DuplicateKey)
{
// mwx.WriteError.Message contains the duplicate key error message
return true;
}
return false;
});
}
Similarly, if you're using await
, that will throw an AggregateException
as well.
To avoid the added complexity of the AggregateException
wrapping the mongo exception, you can call GetAwaiter().GetResult()
instead of Wait()
:
try
{
commandsCollection.InsertOneAsync(doc).GetAwaiter().GetResult();
}
catch(MongoWriteException mwx)
{
if (mwx.WriteError.Category == ServerErrorCategory.DuplicateKey)
{
// mwx.WriteError.Message contains the duplicate key error message
}
}
This is an async Task, you're missing the await
await commandsCollection.InsertOneAsync(bson);
https://github.com/mongodb/mongo-csharp-driver/blob/master/README.md
Further to @JonnyHK reply you can do the same when inserting many.
collection.InsertManyAsync(doc, new InsertManyOptions { IsOrdered = false }).Wait();
would be wrapped in try/catch;
try
{
collection.InsertManyAsync(doc, new InsertManyOptions { IsOrdered = false }).Wait();
}
catch (AggregateException aggEx)
{
aggEx.Handle(x =>
{
var mwx = x as MongoBulkWriteException;
return mwx != null && mwx.WriteErrors.All(e => e.Category == ServerErrorCategory.DuplicateKey);
});
}
I am using VS 2015 and tried all the way to add data using InsertOne /InsertOneAsync, but none of working.
Code is here:
// Create a MongoClient object by using the connection string
_client = new MongoClient();
//Use the MongoClient to access the server
_database = _client.GetDatabase("ratednext");
//get mongodb collection
var Collec = _database.GetCollection<BsonDocument>("computers");
var documnt = new BsonDocument
{
{"Brand","Dell"},
{"Price","400"},
{"Ram","8GB"},
{"HardDisk","1TB"},
{"Screen","16inch"}
};
try
{
Collec.InsertOneAsync(documnt).GetAwaiter().GetResult();
}
catch (AggregateException aggEx)
{
aggEx.Handle(x =>
{
var mwx = x as MongoWriteException;
if (mwx != null && mwx.WriteError.Category == ServerErrorCategory.DuplicateKey)
{
// mwx.WriteError.Message contains the duplicate key error message
return true;
}
return false;
});
}