如何在新的 mongo C# 驱动程序中执行 findAll 并使其同步

How to do findAll in the new mongo C# driver and make it synchronous

我使用官方的 C# 驱动程序做了一个 FindAll 并升级到新的驱动程序 2.0。 FindAll 已过时,已替换为 Find。我正在尝试转换一个简单的方法,该方法 return 给我一个 Class1 的列表。在他们的文档中找不到使用 POCO 的真实示例

var collection = database.GetCollection<ClassA>(Collection.MsgContentColName); return collection.FindAll().ToList();

有人可以帮我转换 2.0 驱动程序和 return 列表而不是任务吗?

您可以这样做以使用 2.0 驱动程序实现相同的效果,

var collection = database.GetCollection<ClassA>(Collection.MsgContentColName);
var doc = collection.Find(filter).ToListAsync();
doc.Wait();
return doc.Result;

编辑:

他们决定重新添加同步支持(尽管异步对于 IO 操作仍然更可取)因此您可以简单地使用:

var list = collection.Find(_ => true).ToList();

原文:

不要同步阻塞异步代码。这对性能不利,并可能导致死锁。

如果您想让您的应用程序保持同步,建议您继续使用旧的同步驱动程序。

在新的 v2.0 驱动程序中,async 选项应如下所示:

async Task FooAsync()
{
    var list = await collection.Find(_ => true).ToListAsync();
}

这是 MongoDb C# Driver 2.2

新的 C# 驱动程序是异步的。不管喜不喜欢,都应该处理。以后会派上用场的。但是现在...

在下面的代码中,由于代码 "result.GetAwaiter().GetResult();",异步调用实际上变成了同步调用。这使得异步代码在正常流程中最终执行。

    static void MongoGoNow()
    {
        IMongoCollection<ClassA> collection = db.GetCollection<ClassA>(Collection.MsgContentColName);
        var result = TestFind(collection);
        result.GetAwaiter().GetResult();
        //What's next???
    }

    static async Task TestFind(IMongoCollection<ClassA> MyCollection)
    {
        var filter = new BsonDocument();
        var count = 0;
        using (var cursor = await MyCollection.FindAsync(filter))
        {
            while (await cursor.MoveNextAsync())
            {
                var batch = cursor.Current;
                foreach (var document in batch)
                {
                    // process document
                    count++;
                }
            }
        }       

您还可以合并 Main 方法中的最后两行代码,如下所示:

    static void MongoGoNow()
    {
        IMongoCollection<ClassA> collection = db.GetCollection<ClassA>(Collection.MsgContentColName);
        TestFind(collection).GetAwaiter().GetResult();
        //What's next???
    }

在 MongoDb 版本 2.2.4 中,实现发生了一些变化。 按照最佳实践,让我们像这样构建 MongoDb 连接:

public static class PatientDb
{
    public static IMongoCollection<Patient> Open()
    {
        var client = new MongoClient("mongodb://localhost");
        var db = client.GetDatabase("PatientDb");
        return db.GetCollection<Patient>("Patients");
    } 
}

现在返回 IMongoCollection 的接口,而不是像 MongoCollection 这样的具体 class 的实例。不再需要创建服务器实例来获取数据库,客户端可以直接访问数据库。

然后在controller中是这样做的:

public class PatientController : ApiController
{
    private readonly IMongoCollection<Patient> _patients;

    public PatientController()
    {
        _patients = PatientDb.Open();
    }
    public IEnumerable<Patient> Get()
    {
        return _patients.Find(new BsonDocument()).ToEnumerable();
    }
}

其中 _patients 是一个 IMongoCollection 并检索所有患者而不是使用 FindAll() 现在使用 Find() 其中过滤器是 BsonDocument 的新实例.

要检索所有内容,您可以根据 documentation

使用 空过滤器

FilterDefinition<T>.Empty

例如

    public async Task<IEnumerable<ClassA>> GetAllAsync() =>
                await database.GetCollection<ClassA>(Collection.MsgContentColName)
               .Find(FilterDefinition<ClassA>.Empty).ToListAsync();

这相当于 FindAll(),

var list = await collection.Find(new BsonDocument()).ToListAsync();