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

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

我正在使用 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 }"
    }})

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

所以我的问题是插入现有 _id 时对 InsertOneAsync 有什么期望?

Visual Studio中的代码:

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

这是一个异步任务,您缺少等待

await commandsCollection.InsertOneAsync(bson);

https://github.com/mongodb/mongo-csharp-driver/blob/master/README.md

如果您在 async 方法中执行此操作,那么 Brduca 的答案将起作用(并且更可取),否则您可以在从 Task 返回的 Wait() 上调用InsertOneAsync 调用以确保您的应用程序保持足够长的时间以查看重复键异常:

commandsCollection.InsertOneAsync(doc).Wait();

如果插入因重复键而失败,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;
    });
}

同样,如果您使用 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
    }
}

进一步@JonnyHK 回复你可以在插入很多时做同样的事情。

collection.InsertManyAsync(doc, new InsertManyOptions { IsOrdered = false }).Wait();

将被包裹在 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);
    });
}