可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I was using official C# driver to do a FindAll
and upgraded to the new driver 2.0. FindAll
is obsolete and is replaced with Find. I am trying to convert a simple method that returns me a list of Class1
. Cant find a realistic example using a POCO in their documentation
var collection = database.GetCollection<ClassA>(Collection.MsgContentColName);
return collection.FindAll().ToList();
Can someone please help me convert with 2.0 driver and return a list and not a task?
回答1:
you could do this to achieve the same using 2.0 driver,
var collection = database.GetCollection<ClassA>(Collection.MsgContentColName);
var doc = collection.Find(filter).ToListAsync();
doc.Wait();
return doc.Result;
回答2:
EDIT:
They decided to add back synchronous support (although async is still preferable for IO operations) so you can simply use:
var list = collection.Find(_ => true).ToList();
Original:
Don't block synchronously on asynchronous code. It's bad for performance and could lead to deadlocks.
If you want to keep your application synchronous it's recommended that you keep using the old synchronous driver.
In the new v2.0 driver the async
option should look like this:
async Task FooAsync()
{
var list = await collection.Find(_ => true).ToListAsync();
}
回答3:
With the MongoDb version 2.2.4, the implementation changed a little bit.
Following the best practices let's build the MongoDb connection like this:
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");
}
}
Now is returned a interface of IMongoCollection
instead of instance of a concrete class like MongoCollection
. There is no need of create a instance of server to get the database anymore, the client can reach the database directly.
Then in the controller is done like this:
public class PatientController : ApiController
{
private readonly IMongoCollection<Patient> _patients;
public PatientController()
{
_patients = PatientDb.Open();
}
public IEnumerable<Patient> Get()
{
return _patients.Find(new BsonDocument()).ToEnumerable();
}
}
Where _patients
is a IMongoCollection and to retrieve all Patients instead to use the FindAll()
now is used the Find()
where the filter is an new instance of BsonDocument
.
回答4:
This is with MongoDb C# Driver 2.2
The new C# driver is asynchronous. Like it or not it should be dealt with. It will come into handy in the future. But for now...
In the code below the asynchronous call is effectively made synchronous because of the code "result.GetAwaiter().GetResult();". This makes the asynchronous code execute to finality in the normal flow.
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++;
}
}
}
You could also merge the last two lines of code in the Main method as follows:
static void MongoGoNow()
{
IMongoCollection<ClassA> collection = db.GetCollection<ClassA>(Collection.MsgContentColName);
TestFind(collection).GetAwaiter().GetResult();
//What's next???
}
回答5:
To retrieve all, you can use an empty filter as per the documentation
FilterDefinition<T>.Empty
For example
public async Task<IEnumerable<ClassA>> GetAllAsync() =>
await database.GetCollection<ClassA>(Collection.MsgContentColName)
.Find(FilterDefinition<ClassA>.Empty).ToListAsync();
回答6:
This would be a equivalent to FindAll(),
var list = await collection.Find(new BsonDocument()).ToListAsync();