MongoDB (server v 2.6.7) with C# driver 2.0: How to get the result from InsertOneAsync

 ̄綄美尐妖づ 提交于 2019-12-18 04:08:36

问题


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);

回答1:


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
    }
}



回答2:


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




回答3:


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);
    });
}


来源:https://stackoverflow.com/questions/30102651/mongodb-server-v-2-6-7-with-c-sharp-driver-2-0-how-to-get-the-result-from-ins

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!