web-dev-qa-db-fra.com

Comment faire pour trouver tout dans le nouveau pilote mongo C # et le rendre synchrone

J'utilisais le pilote officiel C # pour effectuer une FindAll et effectuer une mise à niveau vers le nouveau pilote 2.0. FindAll est obsolète et est remplacé par Rechercher. J'essaye 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 non une tâche?

22
Kar

MODIFIER:

Ils ont décidé d’ajouter du support synchrone (bien que l’async soit toujours préférable pour les opérations IO) afin que vous puissiez simplement utiliser:

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

Original:

Ne bloquez pas de manière synchrone sur du code asynchrone. C'est mauvais pour la performance et pourrait mener à des blocages.

Si vous souhaitez conserver votre application synchrone, il est recommandé de continuer à utiliser l'ancien pilote synchrone.

Dans le nouveau pilote v2.0, l'option async devrait ressembler à ceci:

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

Avec la version 2.2.4 de MongoDb, la mise en œuvre a légèrement 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");
    } 
}

Now renvoie une interface de IMongoCollection au lieu d'une instance d'une classe concrète telle que MongoCollection. Il n'est plus nécessaire de créer une instance de serveur pour récupérer la base de données, le client peut accéder directement à la base de données.

Ensuite, 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 une IMongoCollection et pour récupérer tous les patients au lieu d'utiliser la fonction FindAll(), la fonction Find() est maintenant utilisée, le filtre étant une nouvelle instance de BsonDocument.

2
PedroSouki

Ceci est avec MongoDb C # Driver 2.2

Le nouveau pilote C # est asynchrone. Qu'on le veuille ou non, il devrait être traité. Il sera utile dans le futur. Mais pour l'instant... 

Dans le code ci-dessous, l'appel asynchrone est effectivement synchrone en raison du code "result.GetAwaiter (). GetResult ();". Cela rend le code asynchrone exécuter à 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 également fusionner les deux dernières lignes de code dans la méthode Main comme suit:

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

Pour tout récupérer, vous pouvez utiliser un filtre empty selon 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
Elisabeth