lakichemole
Messages postés253Date d'inscriptionvendredi 13 juin 2003StatutMembreDernière intervention18 mai 2009
-
21 mars 2008 à 10:32
ecosmose
Messages postés46Date d'inscriptionvendredi 5 novembre 2004StatutMembreDernière intervention30 septembre 2010
-
30 mars 2008 à 22:08
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.
ecosmose
Messages postés46Date d'inscriptionvendredi 5 novembre 2004StatutMembreDernière intervention30 septembre 2010 30 mars 2008 à 22:08
Juste au passage, vous pouvez vous inspirez de Entreprise Library DAAB qui gére ca aussi...
cs_Dargos
Messages postés13Date d'inscriptionmardi 18 avril 2006StatutMembreDernière intervention27 mars 2008 27 mars 2008 à 23:49
salut, je viens de mettre à jour le zip avec la gestion des tables d'association.
j'ai aussi fourni le dump de la base de données de test (MySql).
pour repondre à vos questions, il est vrai que mon projet ressemble à link. d'ailleurs, j'etais bien degouté quand j'ai vu arriver link qui utilisait la meme technique que moi pour les attributs. la mecanique interne, je crois que c'est bien plus evolué que la mienne :p
sinon, oui, le but de ce projet est de ne plus faire de requettes. et meme mieux : le but est de pouvoir changer de sgbdr sans changer le code. changer les noms de tables ou de columns, en n'ayant qu'à modifier les attributs dans les classes de mapping.
autrement, le but de ce programme est d'avoir des objects "normaux", avec des collection d'objects... mais en sql, le schéma est obligatoirement différent (l'exemple avec les voitures) : on doit desfois passer par des tables d'associations.
j'ai l'habitude de devoir travailler sur des bases imposées (mal faites et souvent changeantes) donc mon prog a été pensé pour s'y addapter. si on veut générer les classes avec leurs attributs, il va falloir faire un autre projet et bien déterminer les besoins ;)
en tout cas, merci à vous pour ces commentaires !
j'en attend d'autres par rapport au support des tables d'association ;)
(il serait peut etre aussi utile de remplir des dictionnary<,> mais dans quel ca ? )
cs_chris81
Messages postés589Date d'inscriptionjeudi 2 octobre 2003StatutMembreDernière intervention29 avril 20082 27 mars 2008 à 11:42
C'est vrai que si nous avions le script de la sgbd servant au test ce serait plus simple pour nous.
lakichemole
Messages postés253Date d'inscriptionvendredi 13 juin 2003StatutMembreDernière intervention18 mai 2009 27 mars 2008 à 11:29
Oui j'ai fais une conf hier soir justement où ils parlaient de Linq et ça ma fait pensé à vous :)
Mais je pense que l'avantage du code de Dargos c'était justement d'éviter un maximum de requête ou je me trompe?
Donc pour moi se serait un complément à Linq je pense qu'il pourrait l'utiliser mais en plus plutôt qu'à la place :).
tmcuh
Messages postés458Date d'inscriptiondimanche 22 décembre 2002StatutMembreDernière intervention18 avril 2009 27 mars 2008 à 11:14
J'ai un peu de mal à comprendre tout le mécanisme car j'ai pas la db que tu utilise pour les tests. C'est très impressionnant comment tu effectue tes jointures. J'aurais voulu tester un peu plus les performances d'un tel système. Car niveau fonctionnel cela me fait penser de plus en plus au language Linq... Il serait simpa à mon avis de pouvoir géré ta database non plus sur base de la base de données, mais d'après le code, en gros le programme est maitre de sa base de données et non dépendant. Ce qui veut dire que les tables serait géré d'après les class et non l'inverse. Ainsi tu ajoute un champs dans tes class et op il se réperctute sur la db (Alter table). Si une nouvelle class arrive.. op elle est créer si elle existe pas encore.
Tu évite ainsi de te trimballer des casseroles d'update des tables, tu garde les données déjà présente et tu gère très simplement les mises à jour de ton programme.... un champs a été changé (Name -> Surname) ... c'est automatiquement répercuté
lakichemole
Messages postés253Date d'inscriptionvendredi 13 juin 2003StatutMembreDernière intervention18 mai 2009 27 mars 2008 à 10:04
Cela dépend si dans ton système tu prévois de dire que telle ou telle propriété est unique tu peut faire les vérifications de ton coté.
En fait en gros si ton système commence à gérer les contraintes sa devient encore plus top :)
tmcuh
Messages postés458Date d'inscriptiondimanche 22 décembre 2002StatutMembreDernière intervention18 avril 2009 27 mars 2008 à 09:59
d'accord avec toi ;)
cs_Dargos
Messages postés13Date d'inscriptionmardi 18 avril 2006StatutMembreDernière intervention27 mars 2008 26 mars 2008 à 19:07
pour la question du "RealInsert", je pense que ce n'est pas à mon systeme de vérifier s'il existe ou pas une clef identique. par exemple, dernierement, j'ai eu une "DuplicatedKeyException", et j'etais bien content d'avoir cette exception justement. apres, c'est peut etre au programmeur de faire ces verification, ou meme des try{insert} catch{update} par exemple.
apres, pour les jointures, j'ai reussi à faire quelque chose de pas mal, mais je me pose encore la question des tables d'associations. je depose donc le nouveau zip.
tmcuh
Messages postés458Date d'inscriptiondimanche 22 décembre 2002StatutMembreDernière intervention18 avril 2009 26 mars 2008 à 14:06
Après quelques tests, il semble que tu ne gère pas le fait qu'un record soit déjà présent avec l'insert. La fonction "RealInsert" va vouloir généré une requête "insert" avant même de tester si le record n'est pas déjà présent [uniquement sur les primary key bien entendu].
Pour le reste ça viendra avec le temps :p
tmcuh
Messages postés458Date d'inscriptiondimanche 22 décembre 2002StatutMembreDernière intervention18 avril 2009 26 mars 2008 à 09:24
Je pense pour ma part Dargos, qu'il faut laisser à l'utilisateur le choix de choisir comment il désire accéder aux champs, car malheureusement, si on ne permet pas les deux (List<> et propriétés) on se ferme des portes pour des hypothétique cas de figures (dynamisme du code par exemple, avec un parcourt de tous les champs).
Pour la question sur les Join (en général) c'est assez difficile, car parfois on interprète du where clause directement dans le ON afin de gagner en perf. exemple select a.*, b.* from a left outer join b on b.key = a.key and b.pu > 10
Tu as donc des fonctions de liaisons et de filtrage.
Mais personnellement je ne permettrait pas ce type de filtrage au moment de la liaison! Car celà t'ouvre une "porte de pandore" qu'il sera difficile de géré. Il faut juste permettre le liaison = (à la rigueur <>) afin de lire et non d'écrire. Car là aussi en écriture c'est pas simple à géré (pas impossible, mais pas simple).
Il reste encore pas mal de boulot si tu veux terminer entièrement ton projet, mais c'est un projet très très intéressant.
Amicalement,
Tmcuh
cs_Dargos
Messages postés13Date d'inscriptionmardi 18 avril 2006StatutMembreDernière intervention27 mars 2008 25 mars 2008 à 21:24
Tmcuh, ce que tu dis par rapport aux "fields", ca me fait grandement penser à un simple DataRow. la raison pour laquelle je n'aime pas les DataRow, c'est qu'il faut connaitre le nom des propriétés en String, et donc à la compilation, on ne peut rien verifier. avec mon systeme, on ne gere que des propriétés donc vérifications à la compilation.
ensuite, si un jour, un champ de la base change, il suffit de modifier l'attribut de la propriété concernée, et rien d'autre ne changera dans le code ! (sauf si on utilisait le nom du champ au lieu d'utiliser des groupes) au fait, pour ca, j'ai aussi modifié le systeme, pour pouvoir donner les noms des propriétés de l'object au lieu de l'appeller par le nom du champ de la base (ce qui donnera des mauvais resultats si ce nom change change).
allez, bientot un update du zip, quand ca sera un peu plus propre pour les jointures ;)
cs_Dargos
Messages postés13Date d'inscriptionmardi 18 avril 2006StatutMembreDernière intervention27 mars 2008 25 mars 2008 à 21:13
salut salut,
ya d'la bonne idée, la ;)
bon, pour l'instant, j'ai reussi à faire des jointures, mais il faut encore que je rende ca plus maniable : dans nos classes, on a souvent une propriété qui est une liste d'objects, et bien, avec une simple ligne, ca genere la requette, et remplis les objects et listes d'objects. par exemple, dans la classe user, j'ai mis une propriété ville qui a un code postal et un nom. il y a une table equivalente dans la base de données, et quand je lance le programme, ca me remplis bien la ville. j'ai aussi fait le test avec une collection de voitures pour le user, et ca marche ausi. je me pause en ce moment des questions par rapport aux inner join et left join, mais je vais m'en sortir ;)
sinon, il est vrai que pour l'instant, on fait nos objects à la main, ce qui est bien mais pas top. pour ca on peut avoir plusieurs possibilités : regarder la base de données, et générer les classes à partir de ca. mais le probleme, je trouve, c'est que la plus part du temps, les objects et la base, c'est pas la meme architecture : exemple avec une table d'association que l'on a pas dans les objects : on fera juste une List<>. alors quelle est la meilleure solution ? peut etre proposer les deux ;)
ce qui serait idéal, ca serait peut etre de générer les objects à partir d'un xml. et au besoin générer le xml à partir de la base !
à débattre :)
cs_chris81
Messages postés589Date d'inscriptionjeudi 2 octobre 2003StatutMembreDernière intervention29 avril 20082 25 mars 2008 à 14:16
a oui vu comme ça ce serait top !!!
tmcuh
Messages postés458Date d'inscriptiondimanche 22 décembre 2002StatutMembreDernière intervention18 avril 2009 25 mars 2008 à 14:14
Créer un générateur n'est pas bien compliqué à partir du moment où tu as un pattern de départ pour savoir comment il faut le gérer. La chose ici a été prise très intelligement à mon sens. Dargos s'est interressé d'abord au mécanisme et par la suite, si il le désire, il n'aura plus qu'à généré les classes sur bases d'informations divers (xml, sql, txt, etc.) et il retombera dans ces mécanisme et aura ainsi un système semi-dynamique très interressant, car on pourrait prévoir que dans l'avenir, on choisirerais la DB, il génèrerais les class sous forme dll, dès qu'une table change, la dll se recompile avant le démarrage et prenne en compte le nouveau champs et ça c'est le top du top :p
cs_chris81
Messages postés589Date d'inscriptionjeudi 2 octobre 2003StatutMembreDernière intervention29 avril 20082 25 mars 2008 à 14:00
Salut, je viens de tester ta source en fait je pensais qu'on se liait à un sgbd et qu'on créer les classes pour l'O/R.
En fait non , c'est comme en java tu te tapes tout à la main :).
Sinon le setup que j'ai dan sma signature fait cela, si des gens sont interressés je viens d'améliorer ma source mais pour MySQL.
++
tmcuh
Messages postés458Date d'inscriptiondimanche 22 décembre 2002StatutMembreDernière intervention18 avril 2009 25 mars 2008 à 09:22
Pour reparler des class "dynamique", il faut à mon avis utiliser une propriétés dans une class "Fields" qui contiendrais tous les fields de la table dans SQL. Tu as ainsi un accès simplifié pour ceux que tu as besoin pour ta programmation (ex : maclass.Id, maclass.Name) et aussi les autres champs qui pourrait être ajouté et utilisés (ex : maclass.Fields["Age"]).
Tu devrais avoir ainsi une fonctionnalité très avancés pour l'insert,update, delete dans ton code avec n'importe quel champs de la table géré. Après bon pour ce qui est des nouvelle table que l'utilisateur pourrait mettre et qui ne sont pas géré par le système on pourrait convenir d'un "générateur de class"... tout un programme.
Si tu arrive à sortir ça... chapeau bas :p
Amicalement,
Tmcuh
cs_Dargos
Messages postés13Date d'inscriptionmardi 18 avril 2006StatutMembreDernière intervention27 mars 2008 21 mars 2008 à 18:20
effectivement, pour la puissance des procedures stockées. bien que les curseurs soient lents, ils sont quand meme plus rapides que plein de requettes pour faire la meme chose !
par contre, je peux quand meme faire en sorte de supporter les procédures stockées de maniere simple.
pour l'instant, je continue le programme vers le support des jointures. on verra plus tard pour les procedures stockées ;)
a l'heure actuelle, on peut les executer "a la main" avec mon systeme, c'est deja ca ;)
lakichemole
Messages postés253Date d'inscriptionvendredi 13 juin 2003StatutMembreDernière intervention18 mai 2009 21 mars 2008 à 18:11
Nan mais en fait quand je parlais de perf c'est genre en PL SQL tu crée un curseur tu le parcour et suivant le résultat tu fait d'autre trucs et ça c'est beaucoup plus rapide si c'est oracle qui elle fait plutot que de d'abord executer la requête coté code.
Puis en fonction de se qu'elle retourne refaire une autre requête derière.
Et si tu implémente les procédure stockées y a pas grand chose à faire à par le nom de la fonction se qu'elle retourne et les paramètre, et là tu peux pas trop réinventé la roue je pense?
cs_Dargos
Messages postés13Date d'inscriptionmardi 18 avril 2006StatutMembreDernière intervention27 mars 2008 21 mars 2008 à 17:54
pour le coté PL SQL par exemple, avec mon systeme on va pouvoir le faire en faisant dans la classe OracleDbMap les override qu'il faut.
ensuite, pour les procedures stockées, au debut j'avais prevu ca, mais je l'ai enlevé car mal géré. mais maintenant, je peux le rajouter, ce sera facile (et mieux géré qu'au début :p )
ensuite, je me suis appliqué pour les perfs : toutes les requettes (gérées avec des iDataParameters) sont stockées et réutilisées au besoin, donc le gros calcul sera fait uniquement pour la premiere des requetes identiques.
aussi pour les perfs, il peut etre lent de faire le tour des GetProperties() d'un object et de recupérer son attribut à chaque requette. pour cela, j'ai géré une dictionary qui stoque les clefs PropertyInfo/DbColumnAttribute. donc c'est aussi amélioré.
alors apres, pour le coup des tables par classe, c'est vrai que c'est pas terrible. seulement, pour l'instant, c'est suffisant. mais effectivement, on va vite avoir desoin de jointures. justement, j'y reflechis. je pense mettre un parametre optionnel à DbColumnAttribute pour specifier la table jointe, avec les conditions de jointure. mais ca ne va pas etre si simple que ca. il faut encore que j'en definisse l'architecture. a voir donc ;)
et ausi, coté code, si certaines choses paraisent floues, n'hesitez pas à me demander :) c'est peut etre aussi que le code n'est pas assez clair, et c'est donc à coriger ;)
Dargos
tmcuh
Messages postés458Date d'inscriptiondimanche 22 décembre 2002StatutMembreDernière intervention18 avril 2009 21 mars 2008 à 12:59
J'ai pas encore testé, mais Wahaaa... Le système semble tellement bien imbriqué. Très peu de code de conversion de type de db.
Un seul défaut peut être est qu'il fonctionne uniquement sur base de classe, si tu veux faire un système personnalisé par personne en gardant le "coeur" intacte, tu te dois d'avoir des classes de bases exemple pour les camions. Mais si un utilisateur dit "tiens, je rajouterais bien un champs pour connaitre les caractéristiques du pneu avant droit", il faut que le système puisse récupérer cette info et la mettre à jour. Si tu arrive à ça, alors chapeau. Déjà là, c'est un très bon code, j'ai même appris des choses, ça reste encore un peu flou, mais le code est très bon :)
Amicalement,
Tmcuh
lakichemole
Messages postés253Date d'inscriptionvendredi 13 juin 2003StatutMembreDernière intervention18 mai 2009 21 mars 2008 à 10:32
Ca m'a l'air pas mal dutout je m'était dis un jour que je ferais ça!:)
Pour nos applis au boulot d'ailleur, puis finalement j'ai abandonné car je pense que pour les perfs c'est pas top faudrais tester mais je pense que ton truc est parfait pour une petite appli ou des petites requêtes car mon avis c'est moin performant qu'un PL SQL.
Mais bon encore une fois faudrai tester :).
On a eu pas mal de problèmes de perfs car on voulais trop faire de traitements coté code et pas assez coté procédures stockée.
30 mars 2008 à 22:08
27 mars 2008 à 23:49
j'ai aussi fourni le dump de la base de données de test (MySql).
pour repondre à vos questions, il est vrai que mon projet ressemble à link. d'ailleurs, j'etais bien degouté quand j'ai vu arriver link qui utilisait la meme technique que moi pour les attributs. la mecanique interne, je crois que c'est bien plus evolué que la mienne :p
sinon, oui, le but de ce projet est de ne plus faire de requettes. et meme mieux : le but est de pouvoir changer de sgbdr sans changer le code. changer les noms de tables ou de columns, en n'ayant qu'à modifier les attributs dans les classes de mapping.
autrement, le but de ce programme est d'avoir des objects "normaux", avec des collection d'objects... mais en sql, le schéma est obligatoirement différent (l'exemple avec les voitures) : on doit desfois passer par des tables d'associations.
j'ai l'habitude de devoir travailler sur des bases imposées (mal faites et souvent changeantes) donc mon prog a été pensé pour s'y addapter. si on veut générer les classes avec leurs attributs, il va falloir faire un autre projet et bien déterminer les besoins ;)
en tout cas, merci à vous pour ces commentaires !
j'en attend d'autres par rapport au support des tables d'association ;)
(il serait peut etre aussi utile de remplir des dictionnary<,> mais dans quel ca ? )
27 mars 2008 à 11:42
27 mars 2008 à 11:29
Mais je pense que l'avantage du code de Dargos c'était justement d'éviter un maximum de requête ou je me trompe?
Donc pour moi se serait un complément à Linq je pense qu'il pourrait l'utiliser mais en plus plutôt qu'à la place :).
27 mars 2008 à 11:14
Tu évite ainsi de te trimballer des casseroles d'update des tables, tu garde les données déjà présente et tu gère très simplement les mises à jour de ton programme.... un champs a été changé (Name -> Surname) ... c'est automatiquement répercuté
27 mars 2008 à 10:04
En fait en gros si ton système commence à gérer les contraintes sa devient encore plus top :)
27 mars 2008 à 09:59
26 mars 2008 à 19:07
apres, pour les jointures, j'ai reussi à faire quelque chose de pas mal, mais je me pose encore la question des tables d'associations. je depose donc le nouveau zip.
26 mars 2008 à 14:06
Pour le reste ça viendra avec le temps :p
26 mars 2008 à 09:24
Pour la question sur les Join (en général) c'est assez difficile, car parfois on interprète du where clause directement dans le ON afin de gagner en perf. exemple select a.*, b.* from a left outer join b on b.key = a.key and b.pu > 10
Tu as donc des fonctions de liaisons et de filtrage.
Mais personnellement je ne permettrait pas ce type de filtrage au moment de la liaison! Car celà t'ouvre une "porte de pandore" qu'il sera difficile de géré. Il faut juste permettre le liaison = (à la rigueur <>) afin de lire et non d'écrire. Car là aussi en écriture c'est pas simple à géré (pas impossible, mais pas simple).
Il reste encore pas mal de boulot si tu veux terminer entièrement ton projet, mais c'est un projet très très intéressant.
Amicalement,
Tmcuh
25 mars 2008 à 21:24
ensuite, si un jour, un champ de la base change, il suffit de modifier l'attribut de la propriété concernée, et rien d'autre ne changera dans le code ! (sauf si on utilisait le nom du champ au lieu d'utiliser des groupes) au fait, pour ca, j'ai aussi modifié le systeme, pour pouvoir donner les noms des propriétés de l'object au lieu de l'appeller par le nom du champ de la base (ce qui donnera des mauvais resultats si ce nom change change).
allez, bientot un update du zip, quand ca sera un peu plus propre pour les jointures ;)
25 mars 2008 à 21:13
ya d'la bonne idée, la ;)
bon, pour l'instant, j'ai reussi à faire des jointures, mais il faut encore que je rende ca plus maniable : dans nos classes, on a souvent une propriété qui est une liste d'objects, et bien, avec une simple ligne, ca genere la requette, et remplis les objects et listes d'objects. par exemple, dans la classe user, j'ai mis une propriété ville qui a un code postal et un nom. il y a une table equivalente dans la base de données, et quand je lance le programme, ca me remplis bien la ville. j'ai aussi fait le test avec une collection de voitures pour le user, et ca marche ausi. je me pause en ce moment des questions par rapport aux inner join et left join, mais je vais m'en sortir ;)
sinon, il est vrai que pour l'instant, on fait nos objects à la main, ce qui est bien mais pas top. pour ca on peut avoir plusieurs possibilités : regarder la base de données, et générer les classes à partir de ca. mais le probleme, je trouve, c'est que la plus part du temps, les objects et la base, c'est pas la meme architecture : exemple avec une table d'association que l'on a pas dans les objects : on fera juste une List<>. alors quelle est la meilleure solution ? peut etre proposer les deux ;)
ce qui serait idéal, ca serait peut etre de générer les objects à partir d'un xml. et au besoin générer le xml à partir de la base !
à débattre :)
25 mars 2008 à 14:16
25 mars 2008 à 14:14
25 mars 2008 à 14:00
En fait non , c'est comme en java tu te tapes tout à la main :).
Sinon le setup que j'ai dan sma signature fait cela, si des gens sont interressés je viens d'améliorer ma source mais pour MySQL.
++
25 mars 2008 à 09:22
Tu devrais avoir ainsi une fonctionnalité très avancés pour l'insert,update, delete dans ton code avec n'importe quel champs de la table géré. Après bon pour ce qui est des nouvelle table que l'utilisateur pourrait mettre et qui ne sont pas géré par le système on pourrait convenir d'un "générateur de class"... tout un programme.
Si tu arrive à sortir ça... chapeau bas :p
Amicalement,
Tmcuh
21 mars 2008 à 18:20
par contre, je peux quand meme faire en sorte de supporter les procédures stockées de maniere simple.
pour l'instant, je continue le programme vers le support des jointures. on verra plus tard pour les procedures stockées ;)
a l'heure actuelle, on peut les executer "a la main" avec mon systeme, c'est deja ca ;)
21 mars 2008 à 18:11
Puis en fonction de se qu'elle retourne refaire une autre requête derière.
Et si tu implémente les procédure stockées y a pas grand chose à faire à par le nom de la fonction se qu'elle retourne et les paramètre, et là tu peux pas trop réinventé la roue je pense?
21 mars 2008 à 17:54
ensuite, pour les procedures stockées, au debut j'avais prevu ca, mais je l'ai enlevé car mal géré. mais maintenant, je peux le rajouter, ce sera facile (et mieux géré qu'au début :p )
ensuite, je me suis appliqué pour les perfs : toutes les requettes (gérées avec des iDataParameters) sont stockées et réutilisées au besoin, donc le gros calcul sera fait uniquement pour la premiere des requetes identiques.
aussi pour les perfs, il peut etre lent de faire le tour des GetProperties() d'un object et de recupérer son attribut à chaque requette. pour cela, j'ai géré une dictionary qui stoque les clefs PropertyInfo/DbColumnAttribute. donc c'est aussi amélioré.
alors apres, pour le coup des tables par classe, c'est vrai que c'est pas terrible. seulement, pour l'instant, c'est suffisant. mais effectivement, on va vite avoir desoin de jointures. justement, j'y reflechis. je pense mettre un parametre optionnel à DbColumnAttribute pour specifier la table jointe, avec les conditions de jointure. mais ca ne va pas etre si simple que ca. il faut encore que j'en definisse l'architecture. a voir donc ;)
et ausi, coté code, si certaines choses paraisent floues, n'hesitez pas à me demander :) c'est peut etre aussi que le code n'est pas assez clair, et c'est donc à coriger ;)
Dargos
21 mars 2008 à 12:59
Un seul défaut peut être est qu'il fonctionne uniquement sur base de classe, si tu veux faire un système personnalisé par personne en gardant le "coeur" intacte, tu te dois d'avoir des classes de bases exemple pour les camions. Mais si un utilisateur dit "tiens, je rajouterais bien un champs pour connaitre les caractéristiques du pneu avant droit", il faut que le système puisse récupérer cette info et la mettre à jour. Si tu arrive à ça, alors chapeau. Déjà là, c'est un très bon code, j'ai même appris des choses, ça reste encore un peu flou, mais le code est très bon :)
Amicalement,
Tmcuh
21 mars 2008 à 10:32
Pour nos applis au boulot d'ailleur, puis finalement j'ai abandonné car je pense que pour les perfs c'est pas top faudrais tester mais je pense que ton truc est parfait pour une petite appli ou des petites requêtes car mon avis c'est moin performant qu'un PL SQL.
Mais bon encore une fois faudrai tester :).
On a eu pas mal de problèmes de perfs car on voulais trop faire de traitements coté code et pas assez coté procédures stockée.