Skip to content

Pourquoi vous devriez toujours utiliser Find() plutôt que SingleOrDefault() ou FirstOrDefault()

Récupérer une entité par son identifiant est quelque chose que l’on fait quotidiennement dans nos applications, mais le fait-on vraiment correctement ?

Une histoire de performance

Vous me direz, comment peut-on mal faire quelque chose d’aussi simple ? Et je vous répondrai tout simplement, faites comme moi et ne lisez pas la documentation des choses que vous pensez aussi simple.

Penchons-nous un peu sur la documentation de la méthode Find de l’implémentation du DbSet d’EF Core.

Finds an entity with the given primary key values. If an entity with the given primary key values is being tracked by the context, then it is returned immediately without making a request to the database. Otherwise, a query is made to the database for an entity with the given primary key values and this entity, if found, is attached to the context and returned. If no entity is found, then null is returned.

Plutôt explicite non ? Pour les anglophobes, la documentation nous explique que la méthode permet de chercher une entité via la clef primaire passée en paramètre. Si cette clef est déjà traquée par le contexte, l’entité sera directement retournée sans faire de requête vers la base de données, sinon, l’entité sera attachée et ensuite retournée.

Find() Vs SingleOrDefault(), implémentation

Concrètement, voici ce que ça donnerait au niveau du code :

// Find
var beer = context.Find(2); // Une requête est exécutée, l’entité n’étant pas encore traqués, EF va exécuter une requête vers la Db, traquer l’entité et la renvoyer
var secondBeer = context.Find(2); // L’entité est déjà traqué, EF va directement retourner l’entité correspondante

// SingleOrDefault
var beer = context.SingleOrDefault(b => b.Id == 2); // EF va exécuter la requête vers la Db et renvoyer l’entité
var secondBeer = context.SingleOrDefault(b => b.Id == 2); // EF va à nouveau exécuter la requête, sans tenir compte du contexte

// Mélange des deux
var beer = context.SingleOrDefault(b => b.Id == 2); // EF va exécuter la requête vers la Db et renvoyer l’entité
var secondBeer = context.Find(2); // L’entité est traqué par le contexte car récupéré précédemment, aucune requête ne partira vers la Db

Petite subtilité, bien que SingleOrDefault() (ou FirstOrDefault() / First() / Single()) ne tienne pas compte des entités traquée pour renvoyer son résultat, cette méthode rajoute quand même l’entité au contexte actuel. Ce qui nous donne le 3ème cas d’exemple où Find() tire profit des entités traquées par les autres méthodes pour éviter un aller / retour.

Avantages de Find()

  • Éviter des allers / retours inutiles vers la base de données
  • Méthode propre au DbSet, on ne dépend pas de Linq

Inconvénients de Find()

  • Ne permets les recherches que par la clef primaire

En conclusion

C’est, selon moi, une petite habitude à prendre qui nous permet, dans certains cas, d’optimiser le chargement de nos entités, alors pourquoi s’en priver ? Je n’utilise désormais plus que Find() quand je dois récupérer des données par l’identifiant primaire.

Et vous, quelle petite spécifité du quotidien avez-vous rencontrée récemment ? Saviez-vous que Find() permettait cette petite optimisation ?

Published inC#EntityFramework

Be First to Comment

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.

0 Partages
Partagez
Tweetez
Partagez