Comment faire findAll dans le nouveau pilote mongo C# et le rendre synchrone
j'utilisais le pilote officiel C# pour faire un FindAll
et mis à niveau vers le nouveau pilote 2.0. FindAll
est obsolète et remplacée par Trouver. Je suis en train de convertir une méthode simple qui me renvoie une liste de Class1
. Impossible de trouver un exemple réaliste en utilisant un POCO dans leur documentation
var collection = database.GetCollection<ClassA>(Collection.MsgContentColName);
return collection.FindAll().ToList();
quelqu'un peut-il s'il vous plaît m'aider à convertir avec le pilote 2.0 et retourner une liste et pas une tâche?
5 réponses
Vous pouvez faire cela pour obtenir le même pilote en utilisant 2.0,
var collection = database.GetCollection<ClassA>(Collection.MsgContentColName);
var doc = collection.Find(filter).ToListAsync();
doc.Wait();
return doc.Result;
EDIT:
ils ont décidé d'ajouter le support synchrone (bien que async soit toujours préférable pour les opérations IO) donc vous pouvez simplement utiliser:
var list = collection.Find(_ => true).ToList();
Origine:
ne bloquez pas le code asynchrone de façon synchrone. C'est mauvais pour la performance et ça pourrait mener à des blocages.
si vous voulez garder votre application synchrone, il est recommandé de continuer à utiliser l'ancien pilote synchrone.
dans le nouveau v2.0 pilote le async
option devrait ressembler à ceci:
async Task FooAsync()
{
var list = await collection.Find(_ => true).ToListAsync();
}
avec la version 2.2.4 de MongoDb, l'implémentation a un peu changé. En suivant les meilleures pratiques, construisons la connexion MongoDb comme ceci:
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");
}
}
renvoie maintenant une interface de IMongoCollection
au lieu de l'instance d'une classe concrète comme MongoCollection
. Il n'y a plus besoin de créer une instance de serveur pour obtenir la base de données, le client peut accéder directement à la base de données.
Puis dans le contrôleur est fait comme ceci:
public class PatientController : ApiController
{
private readonly IMongoCollection<Patient> _patients;
public PatientController()
{
_patients = PatientDb.Open();
}
public IEnumerable<Patient> Get()
{
return _patients.Find(new BsonDocument()).ToEnumerable();
}
}
Où _patients
est un IMongoCollection et à récupérer tous les Patients, au lieu d'utiliser le FindAll()
maintenant est utilisé le Find()
où le filtre est une nouvelle instance de BsonDocument
.
Dans le code ci-dessous l'appel asynchrone est effectivement rendue synchrone, car le code ".GetAwaiter ().GetResult ();". Ceci fait que le code asynchrone s'exécute jusqu'à la finalité dans le flux normal.
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++;
}
}
}
Vous pouvez aussi fusionner les deux dernières lignes de code dans le Méthode principale comme suit:
static void MongoGoNow()
{
IMongoCollection<ClassA> collection = db.GetCollection<ClassA>(Collection.MsgContentColName);
TestFind(collection).GetAwaiter().GetResult();
//What's next???
}
pour récupérer tout, vous pouvez utiliser un vider le filtre par le documentation
FilterDefinition<T>.Empty
Par exemple
public async Task<IEnumerable<ClassA>> GetAllAsync() =>
await database.GetCollection<ClassA>(Collection.MsgContentColName)
.Find(FilterDefinition<ClassA>.Empty).ToListAsync();