如何在新的 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();
我使用官方的 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();