了解MongoDB新C#驱动程序中的更改(异步和等待)

11
新的C#驱动程序完全使用异步方式,并且在我看来,对旧的设计模式(如n层体系结构中的DAL)进行了一些小的改进。
在我的Mongo DAL中,我通常会这样做:
public T Insert(T entity){
     _collection.Insert(entity);
     return entity;
}

这样我就能获得持久化的ObjectId了。
现在,所有的操作都是异步的,比如InsertOneAsync。当InsertOneAsync完成时,Insert方法怎样才能返回entity呢?你可以举个例子吗?
2个回答

18

了解基础的async/await很有帮助,因为它是一种有些泄漏的抽象,并有许多陷阱。

基本上,你有两个选择:

  • 保持同步。在这种情况下,可以分别使用.Result.Wait()处理异步调用,例如下面的代码:

    // Insert:
    collection.InsertOneAsync(user).Wait();
    
    // FindAll:
    var first = collection.Find(p => true).ToListAsync().Result.FirstOrDefault();
    
  • 在您的代码库中采用异步方式。不幸的是,这种异步方式相当“传染”,因此要么将几乎所有内容转换为异步方式,要么不转换。请注意,错误地混合同步和异步会导致死锁。使用异步方式具有许多优点,因为在 MongoDB 仍在工作时,您的代码可以继续运行,例如。

  • // FindAll:
    var task = collection.Find(p => true).ToListAsync();
    // ...do something else that takes time, be it CPU or I/O bound
    // in parallel to the running request. If there's nothing else to 
    // do, you just freed up a thread that can be used to serve another 
    // customer...
    // once you need the results from mongo:
    var list = await task;
    

使用同步的MongoDB就像在经典ASP应用程序中调用SQL数据库一样?这会导致整个网站被锁定,直到调用结束吗? - RPDeshaies
你需要添加特定的内容才能使 await task 行起作用吗?它一直在喊叫需要在某个 async 对象上执行 await.. 但是当然已经有 .ToListAsync() 存在了。有任何想法可能是什么问题吗?@mnemosyn - Mark Pieszak - Trilon.io
@mcpDESIGNS:await 只能在声明为 async 的方法中使用。 - mnemosyn
通常我会在Node/mongoose中使用Mongo,所以在C#的世界里这对我来说有些奇怪。我尝试了async Task FooAsync(IMongoCollection<BsonDocument> collection)作为一个方法,它可以工作。谢谢。我想把它们链接在一起可能是接下来要困扰我的部分...哈哈 - Mark Pieszak - Trilon.io
异步/等待应该与Node的操作非常接近...无论如何,我建议您退后一步,从一个不使用异步库的小型异步控制台应用程序开始...此外,IMongoCollection<BsonDocument>对我来说看起来不太好(为什么不是强类型?)但这离原始问题太远了... - mnemosyn

0
在我的情况下:当我遇到这个错误时:

The source IQueryable doesn't implement IAsyncEnumerable. Only sources that implement IAsyncEnumerable can be used for Entity Framework asynchronous operations.

我已经按照以下方式为 MongoDB 实现了异步 where 函数。
public async Task<IEnumerable<TEntity>> Where(Expression<Func<TEntity, bool>> expression = null)
{
     return await context.GetCollection<TEntity>(typeof(TEntity).Name, expression).Result.ToListAsync();
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接