Accès aux données avec le micro-ORM Dapper
Un tutoriel de Thomas Levesque
Le 2013-10-29 14:17:30, par tomlev, Rédacteur/Modérateur
Bonjour,
Cette discussion est destinée à recevoir vos commentaires sur l'article Accès aux données avec Dapper
Cette discussion est destinée à recevoir vos commentaires sur l'article Accès aux données avec Dapper
Pour accéder à une base de données avec .NET, on a traditionnellement le choix entre deux grandes approches : utiliser un ORM (Object-Relational Mapper), ou requêter directement en SQL à l'aide d'ADO.NET. Si les ORM permettent généralement de gagner du temps, ce sont aussi souvent des « usines à gaz », ce qui les rend peu adaptés pour certaines applications. Mais d'un autre côté, l'API ADO.NET pour requêter en SQL est un peu laborieuse à utiliser… Il faudrait donc un compromis entre les deux : c'est là qu'intervient Dapper, une petite librairie open-source qui appartient à la catégorie des micro-ORM.
-
tomlevRédacteur/ModérateurSi tu avais lu l'article tu ne poserais pas cette question
En résumé, un ORM complet comme Entity Framework ou NHibernate, c'est certes puissant, mais c'est un peu "usine à gaz"... C'est très lourd, les performances ne sont pas optimales, on ne sait pas trop ce qui se passe derrière, etc
Dapper n'a pas la prétention de faire tout ce que fait un vrai ORM ; il permet surtout de faire du SQL (avec les avantages que ça implique en terme de performance) tout en facilitant certaines tâches qui sont fastidieuses avec l'API ADO.NET standard (requêtes paramétrées, matérialisation d'objets métier).le 31/10/2013 à 10:55 -
tomlevRédacteur/ModérateurPour être clair, je ne dis pas que Entity Framework est une grosse daube et qu'il ne faut surtout pas s'en servir... Je dis simplement que c'est pas adapté à toutes les applications. L'équipe de Stack Overflow s'est donné la peine de créer Dapper parce que les performances d'Entity Framework étaient insuffisantes, je pense pas qu'ils l'aient fait juste pour le plaisir...
D'ailleurs, jette un oeil au comparatif de performances sur le site de Dapper, c'est assez éloquent (évidemment c'est sûrement pas totalement impartial, mais ça donne une idée)
Je ne parle pas en terme d'utilisation ; évidemment que c'est super simple à utiliser. Mais ce qui se passe derrière et assez lourd, et pas du tout transparent. Tu ne contrôles pas (ou très peu) le SQL qui est généré, et si ce n'est pas optimal tu ne peux pas y faire grand chose. Le lazy loading est certes très pratique, mais ça implique des allers-retours supplémentaires vers la DB ; si tu fais des traitements en masse, c'est pas top... Je pourrais citer pas mal d'autres problèmes, mais j'ai la flemme des les écrire.
Bah déjà tu écris le SQL toi-même... Tout ce que fait Dapper, finalement, c'est :
- gérer la déclaration des paramètres de la requête à partir de l'objet de paramètres que tu passes (avec un cache par type pour ne pas faire de la réflexion à chaque appel)
- matérialiser les entités à partir du contenu d'un DataReader (là aussi, avec un cache par type d'entité)
Le code de Dapper n'est vraiment pas long, donc si tu veux fouiller dedans, c'est vite fait... en quelques minutes tu peux commencer à voir le principe. Par contre celui d'EF, je pense qu'il faudrait au moins quelques semaines avant de commencer à comprendre comment ça fonctionne.
Bah écoute, tu fais ce que tu veux... Continue à utiliser EF puisque tu es absolument certain que c'est forcément le meilleur choix dans toutes les situations.
Moi, on m'a appris qu'il fallait toujours utiliser l'outil le plus adapté pour une tâche donnée ; parfois ce sera EF, parfois ce sera Dapper, parfois ce sera encore autre chose...le 31/10/2013 à 12:15 -
katkillerMembre éprouvéJe ne connaissais pas cette librairie !
Elle a vraiment l'air très simple a utiliser (A essayer bien sûr) !
Merci pour la découvertele 29/10/2013 à 16:55 -
Maître KenobiMembre éprouvéBonjour,
peut-on facilement l'adapter au VB ?le 31/10/2013 à 10:08 -
tomlevRédacteur/ModérateurSalut,
Oui bien sûr, du moins je ne vois pas de raison que ce soit pas possible... par contre cela suppose de référencer le binaire (la solution consistant à inclure la source dans le projet ne fonctionnera pas, puisque ce n'est pas du VB)
Ca donnerait quelque chose comme ça (si je ne me plante pas dans la syntaxe VB...) :
Lecture d'une liste d'entités
Code VB.NET : Dim contacts As IEnumerable(Of Contact) = connection.Query(Of Contact)("select * from Contact")
Code VB.NET : 1
2
3Dim result = connection.Query("select count(*) as Count, max(Id) as MaxId from Contact").Single() Dim count As Integer = result.Count Dim maxId As Integer = result.MaxId
Requête paramétrée :
Code VB.NET : 1
2
3Dim results = connection.Query(Of Contact)( _ "select * from Contact where DateOfBirth < @maxDate and FirstName = @firstName", _ New With { .maxDate = New DateTime(1950, 1, 1), .firstName = "George" })
le 31/10/2013 à 10:25 -
stailerMembre chevronnéJe crois avoir vu qu'avec EF aussi y a moyen de faire du SQL.
Tu parles de perf... Euh alors dans ce cas la solution est toute trouvée : je pense que les procs stockées SQL Server sont plus performantes que EF et Dapper. Donc si vraiment t'as besoin de perfs, la solution la plus adaptée est sûrement celle là. A noter d'ailleurs qu'avec EF tu peux mapper aussi des procs stockées. Pourquoi s'en passer en cas de besoin de grandes perfs ?
Ensuite, concernant les requêtes SQL émises par EF y a aussi moyen de voir ce qu'il créée... Je crois que c'est LinqPad dans lequel tu mets ta requête linq et il te montre ce qui va en résulter en SQL. Je m'en sers pas car j'ai pas eu le besoin mais bon, ça existe.le 31/10/2013 à 13:48 -
tomlevRédacteur/ModérateurOui effectivement ; et dans ce cas ça revient un peu au même que ce que fait Dapper, sauf que les paramètres sont passés d'une façon un peu moins pratique à mon sens (un tableau d'objets).
En fait si c'est pour faire une bête requête sur une table, je ne suis pas sûr que ça change grand chose de l'exécuter directement ou via une PS... A part peut-être lors de la 1e exécution d'une requête, parce que la PS sera déjà compilée, alors que la requête devra être parsée.
Pour moi, l'intérêt des PS, c'est pas tellement les performances, c'est plutôt de limiter ce que peuvent faire les applis qui tapent dans la base (par exemple interdire les requêtes directes, mais autoriser les appels à certaines PS). Ca peut aussi être utile pour faire des choses plus complexes qu'une simple requête.
Oui, tu peux faire ça dans Linqpad. Il y a aussi un moyen de le faire en code (pour logger les requêtes par exemple), je me rappelle plus comment exactement. Par contre tu ne peux pas contrôler ce que fait la requête... Par exemple si tu sais, d'après les index que tu as sur ta DB, les stats, qu'il serait plus efficace de faire un jointure qu'un SELECT imbriqué (ou inversement), tu ne peux pas forcer EF à le faire.
C'est notamment pour ça que j'aime bien Dapper : il n'essaie pas de faire des choses qui pourraient être faites plus intelligemment par le développeur, il se contente des tâches qui ne demandent pas trop de réflexion mais qui sont fastidieuses à faire à la main.le 31/10/2013 à 14:04 -
stailerMembre chevronnéIl y a aussi un moyen de le faire en code (pour logger les requêtes par exemple), je me rappelle plus comment exactement.
EDIT :
Je teste ça dès que j'ai 5 minutes :Code : http://stackoverflow.com/questions/1102443/visualize-generated-sql-from-linq-to-entities
le 31/10/2013 à 14:08 -
meziantouMembre émériteEnsuite, concernant les requêtes SQL émises par EF y a aussi moyen de voir ce qu'il crée...
http://weblogs.asp.net/gunnarpeipman/archive/2010/03/16/entity-framework-4-0-optimal-and-horrible-sql.aspxy a aussi un moyen de le faire en code (pour logger les requêtes par exemple), je me rappelle plus comment exactement.le 31/10/2013 à 14:12 -
stailerMembre chevronné@meziantou Ok j'entends bien...
Maintenant je peux te dire aussi qu'à une époque j'ai travaillé avec des gens qui s'en battait du sql et ça y allait à grand coup de "select *" ou de requêtes imbriquées parce qu'ils avaient oublié (ou ne savaient pas faire) les jointures...
Alors bon... le SQL moisi de Linq, il a bon dosle 31/10/2013 à 16:00