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?

21
demandé sur i3arnon 2015-04-18 00:41:25

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;
-9
répondu XtremeBytes 2016-01-12 10:33:44

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();
}
38
répondu i3arnon 2016-09-17 11:03:35

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();
    }
}

_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.

2
répondu PedroSouki 2016-06-28 12:43:05

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???
    }
1
répondu Brett Jones 2015-12-12 09:00:28

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();
0
répondu Elisabeth 2018-06-26 19:05:00