带有C#驱动程序2.0的MongoDB(服务器v 2.6.7):如何从InsertOneAsync获取结果

Fre*_*rik 9 c# mongodb async-await mongodb-.net-driver

我正在使用C#驱动程序2.0测试MongoDB(服务器v 2.6.7).

当我使用插入函数存在InsertOneAsync一个_id存在的文档时,我期待一个像你从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 }"
    }})
Run Code Online (Sandbox Code Playgroud)

但问题是带有C#驱动程序的插入不会抛出异常,我找不到WriteResult插入.当我查看数据库时,似乎什么都没发生.

所以我的问题是InsertOneAsync在插入现有内容时会发生_id什么?

Visual Studio中的代码:

IMongoCollection<BsonDocument> commandsCollection = db.GetCollection<BsonDocument>("Commands");
var bson = new BsonDocument
        {
            {"_id", i.Value},
            {"label", i.Key}
        };
commandsCollection.InsertOneAsync(bson);
Run Code Online (Sandbox Code Playgroud)

Joh*_*yHK 11

如果你是一个内做这个async方法,那么Brduca的回答就可以了(并且是preferrable),否则,你可以调用Wait()Task从返回InsertOneAsync调用,以确保您的应用程序保持足够长的时间看到重复键异常:

commandsCollection.InsertOneAsync(doc).Wait();
Run Code Online (Sandbox Code Playgroud)

如果插入失败,因为重复键时,Wait()会抛出一个AggregateException包含MongoWriteException包含重复的关键细节.

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;
    });
}
Run Code Online (Sandbox Code Playgroud)

同样,如果你正在使用await,那也会抛出一个AggregateException.

为了避免AggregateException包装mongo异常的额外复杂性,您可以调用GetAwaiter().GetResult()而不是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
    }
}
Run Code Online (Sandbox Code Playgroud)