J’ai ramassé un morceau de code qui utilise le pilote MongoDB comme celui-ci pour obtenir un seul object dans une collection … cela ne peut pas être correct, n’est-ce pas? Y a-t-il une meilleure façon de l’obtenir?
IMongoCollection userCollection; .... userCollection.FindAsync(x => x.Id == inputId).Result.ToListAsync().Result.Single();
Oui il y a.
Tout d’abord, n’utilisez pas FindAsync
, utilisez plutôt Find
. Sur le résultat IFindFluent
utilisez la méthode d’extension SingleAsync
et attendez la tâche renvoyée dans une méthode asynchrone:
async Task MainAsync() { IMongoCollection userCollection = ...; var applicationUser = await userCollection.Find(_ => _.Id == inputId).SingleAsync(); }
Le nouveau pilote utilise exclusivement async-wait. Ne bloquez pas dessus en utilisant Task.Result
.
Vous devriez limiter votre requête avant de l’exécuter, sinon vous allez d’abord trouver tous les résultats et ensuite n’en lire qu’un.
Vous pouvez soit spécifier la limite à l’aide de FindOptions
dans FindAsync
, soit utiliser la syntaxe fluide pour limiter la requête avant de l’exécuter:
var results = await userCollection.Find(x => x.Id == inputId).Limit(1).ToListAsync(); ApplicationUser singleResult = results.FirstOrDefault();
Le résultat de ToListAsync
sera une liste, mais puisque vous ToListAsync
le nombre de résultats à 1, cette liste n’aura qu’un seul résultat auquel vous pourrez accéder à l’aide de Linq.
Je n’ai pas pu avoir la méthode:
coll.Find(_ => _.Id == inputId).SingleAsync();
Travailler comme je recevais l’erreur
InvalidOperationException: Sequence contains more than one element c#
J’ai donc fini par utiliser .FirstOrDefault()
Exemple:
public FooClass GetFirstFooDocument(ssortingng templatename) { var coll = db.GetCollection("foo"); FooClass foo = coll.Find(_ => _.TemplateName == templatename).FirstOrDefault(); return foo; }