IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

DataAdapter et DataSet


Sujet :

C#

  1. #1
    Nouveau membre du Club
    Inscrit en
    Novembre 2006
    Messages
    39
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 39
    Points : 26
    Points
    26
    Par défaut DataAdapter et DataSet
    Ya un truc que je ne comprends pas très bien :

    Je viens de voir que le moyen de faire un pont entre un DataSet et la base de donnée, c'est le DataAdapter. Seulement le DataSet comprends plusieurs DataTable, qui ont chacune leur requete pour se remplir, pour effacer un enregistrement, le modifier, ou en ajouter. Mais le DataAdapter ne peut stocker qu'une seule requète pour chaque action de chaque table ... faut t'il autant de DataAdapter qu'on a de tables ?? mais ca me semble pas logique ! Ou alors, faut t'il pour chaque action, transmettre au DataAdapter la commande qu'il doit effectuer ??? J'aimerais savoir ce que je n'ai pas du comprendre dans le fonctionnement , si quelqu'un peut m'aider

  2. #2
    Membre régulier

    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    68
    Détails du profil
    Informations personnelles :
    Âge : 52
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Novembre 2007
    Messages : 68
    Points : 104
    Points
    104
    Par défaut
    Oui, il y a une étroite relation entre l'objet DataAdapter et l'objet Table. Les commandes du DataAdapter reflètent la structure de la Table sur laquelle il s'applique.

    Oui, il faut à priori UN DataAdapter pour chaque Table du DataSet. Généralement, les commandes Insert, Update, Delete sont définies une fois pour toutes. En revanche, il est tout a fait possible de faire évoluer la commande Select en fonction de nos besoins au cours des différentes phases de l'execution de notre programme. Ainsi, on peut dire qu'avec un seul et même DataAdapter nous pouvons effectuer toutes les opérations dont nous aurons besoin pour une seule et même table (il y a évidemment toujours des cas particuliers).

    Là où la confusion s'installe c'est qu'il existe des DataSet fortement typés. Je pense que c'est à cela que vous faites allusion quand vous dites "le DataSet comprends plusieurs DataTable, qui ont chacune leur requete pour se remplir, pour effacer un enregistrement, le modifier, ou en ajouter". C'est vrai que c'est pratique, quelque clics de souris pour ajouter un nouveau fichier DataSet, du drag and drop pour y glisser des tables...

    Mais, en fait, on pourrait presque dire que ce genre de DataSet ne fait pas vraiment parti de .Net. Si on y regarde de plus près, ces DataSet sont produits par un ensemble d'assistants de Visual Studio qui génèrent du code à notre place (en ASP.NET la structure XML est convertie à la compilation). Ainsi, les requêtes que nous voyons dans le designer sont ensuite intégrées dans des DataAdpater. Regardez le code généré vous en ferez le constat. Dans la réalité, le DataSet ou les Tables ne contienent aucune requête SQL. Ce sont bel et bien les DataAdpater qui s'occupent de ce travail.

    Notez que les DataSet fortement typés appliquent une stratégique bien spécifique à laquelle ont peut trouver des avantages mais aussi des inconvéniants.

    Il est tout à fait possible avec .Net d'imaginer une autre stratégie. C'est personnellement ce que je fais. J'ai développé mes propres assistants et j'applique ma propre logique (en locurence une logique métier avec séparation DAL / BOL).

    C'est dire combien tout cela est vaste et puissant.
    Michaël LEBRETON - Developpeur / Formateur indépendant
    http://www.netkoders.com

  3. #3
    Nouveau membre du Club
    Inscrit en
    Novembre 2006
    Messages
    39
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 39
    Points : 26
    Points
    26
    Par défaut
    Merci pour la réponse, cependant je ne passe pas par l'assistant de visual studio etant donné que j'exploite une base MySql avec le driver officiel de mysql pour .net, et j'utilise un DataSet principal qui contient la collection de DataTable. Seulement j'ai vu que le DataAdapter peut reproduire le shéma de la base de donnée, et donc générer toutes les DataTable nécessaires, et c'est de là que viennent mes doutes, car :

    On peut faire : monDataAdapter.fill(monDataSet)
    ou bien : monDataAdapter.fill(monDataSet, "maTable")

    Dans le deuxieme cas, ok, cela ne concerne qu'une seule table, mais dans le premier, cela peut t'il concerner n tables ??

  4. #4
    Membre actif
    Inscrit en
    Août 2006
    Messages
    381
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 381
    Points : 252
    Points
    252
    Par défaut
    Bonjour,

    Dans le deuxieme cas, ok, cela ne concerne qu'une seule table, mais dans le premier, cela peut t'il concerner n tables ??
    Et non cela ne peut concerner qu'une seule table.
    Si tu utilises la méthode tonDataAdapter.Fill(tonDataSet) sans avoir défini le mapping de tables et de colonnes, une nouvelle DataTable va être crée. Cette DataTable portera le nom "Table".
    Si tu définis le mapping de table et de colonnes, aucune DataTable ne sera crée dans le DataSet. La DataTable utilisée sera celle que tu auras défini dans le mapping de table. Les colonnes qui sont présentes dans ta SELECTCOMMAND et qui n'ont pas été mappés seront ajoutés à la table mappée.

    A bientôt
    Bye

  5. #5
    Membre régulier

    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    68
    Détails du profil
    Informations personnelles :
    Âge : 52
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Novembre 2007
    Messages : 68
    Points : 104
    Points
    104
    Par défaut
    Tout à fait d'accord.
    Michaël LEBRETON - Developpeur / Formateur indépendant
    http://www.netkoders.com

  6. #6
    Nouveau membre du Club
    Inscrit en
    Novembre 2006
    Messages
    39
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 39
    Points : 26
    Points
    26
    Par défaut
    Ok , d'accord, mais alors comment mapper les tables ??? existe t'il une solution qui pourrait faire ca automatiquement a partir du shéma de la base de donnée, en reprenant toutes les relations de cle etrangères existantes dans la base ??

    Ou sinon, je vois donc qu'il vaut mieux créer un nouveau DataAdapter pour chaque création de DataTable que l'on ajoute au DataSet, non ? Mais cela oblige pour les relations à devoir toutes les ecrires en dur alors qu'elles existent déjà dans la base de donnée !!

    Ou mieux , existe t'il une classe déjà écrite qui permettent d'exploiter au mieux sa base de donnée sans devoir se taper la réecriture de toutes les contraintes fonctionelles, et tout et tout ??

    Merci en tout cas à tous pour vos lumières !!

  7. #7
    Nouveau membre du Club
    Inscrit en
    Novembre 2006
    Messages
    39
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 39
    Points : 26
    Points
    26
    Par défaut
    Bon j'avance un peu, a taton, j'ai trouvé ce document pour ceux qui aurait le même soucis que moi :

    http://www.supinfo-projects.com/fr/2005/datatype/

    Cela m'aide un peu , mais un probleme reste .... comment bien utiliser les proprietés selectCommand, insertCommand, deleteCommand, et updateCommand quand on travaille sur plusieurs tables ? Car on ne peut traiter qu'une seule table à la fois .... !

  8. #8
    Membre régulier

    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    68
    Détails du profil
    Informations personnelles :
    Âge : 52
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Novembre 2007
    Messages : 68
    Points : 104
    Points
    104
    Par défaut Moi j'ai mon truc à moi
    Voici ma façon de travailler (elle vaut ce qu'elle vaut mais elle répond à mes besoins)

    Je vous présente ci après ma façon de travailler. J'ai d'abord il y a des années implémenté cette solution sous Delphi, puis le l'ai porté sur .Net. Cela fait donc des années que je travail ainsi et je ne l'ai jamais regretté.

    Personnellement, je modélise mes bases de données sur Toad (Anciennement CaseStudio). Si je ne suis pas l'auteur de la base, Toad dispose d'outils de reverse engineering me permettant de récréer un modèle.

    Ce qui est très intéressant avec ce produit, c'est qu'il est customizable. Je peux sans la moindre difficulté ajouter des propriétés sur les champs ou sur les tables (Cela me permet de définir des règles qui ne s'appliqueront pas à la génération du script SQL de création de la base, mais qui seront utilisés par l'assistant dont je parle ci-après). De plus, Toad est Automation.

    Or, Customization + Automation = Je fais ce que je veux.

    J'ai donc développé un assistant Visual Studio qui est capable d'ouvrir un modèle dans Toad, et de l'analyser afin de générer :
    • Un fichier contenant toute la logique d'accès aux données ainsi qu'un certains nombre de classes outils (fichier qui normalement n'est pas à modifié dans l'application).
    • Un fichier de constantes pour tous les éléments de la base. Ces éléments sont compatible avec un modèle d'écriture de requête SQL (fichier qui normalement n'est pas à modifié dans l'application).
    • Un fichier implémentant le modèle d'écriture de requêtes SQL qui me permet d'écrire mes requêtes SQL de façon à ce qu'elles soient compilées. Ainsi, si j'effectue la moindre modification sur la base de données, la moindre requête qui ne fonctionne plus m'est signalée à la compilation (en fait je fait quelque chose qui ressemble un peu à du LINQ depuis des années) (fichier qui normalement n'est pas à modifié dans l'application).
    • Un fichier implémentant l'ensemble des mécanismes communs des Table, DataSet et DataAdapter de l'application au travers de classes virtuelles (fichier qui normalement n'est pas à modifié dans l'application).
    • Un fichier de classes virtuelles surchargeant les précédentes. Chaque table dispose d'une classe virtuelle implémentant les mécanismes de base reflétant sa structure. Les clés, les liaisons, ... tout cela est analysé et codé (fichier qui normalement n'est pas à modifié dans l'application).
    • Un fichier pour chaque table, ne contenant qu'une surcharge vide de la classe virtuelle représentant la table. Ces fichiers ne sont créés que si ils n'existent pas. C'est seulement dans ces fichiers qu'il me reste à travailler. J'y implémente les règles métier.
    • Des objets DataSource adaptés au contextes d'application ASP.NET ou Windows Form me permettant ainsi d'utiliser le même modèle de données dans ces deux contextes très différents.
    J'ai aussi développé un assistant de création de contrôles liés aux données. Un drag and drop depuis cet assistant sur une page ASP.NET ou une form, et automatiquement se crée un contrôle d'accès à la données adapté à la forme de la donnée et à d'éventuelles règles définies dans le modèle Toad. Par exemple, si je glisse le champ Genre de la table client et que dans le modèle Toad est défini que la valeur de ce champ correspond à une liste de possibilités retournée par une procédure stockée appelée ListeDesGenres, alors, automatiquement un DropDown est crée et il s'alimentera tout seul auprès de la procédure stockée.

    Bref, ce que je veux dire c'est que si vos besoins en terme de données sont important, cela vaut vraiment la peine de prendre le temps de réfléchir à un modèle que vous maîtriserez parfaitement et qui sera en parfaite adéquation avec vos besoins.

    Il est évident que cela représente un investissement temps important. Mais si vous saviez le temps que j'ai gagné avec ce modèle. Si vous saviez combien de fois il m'a sauvé la vie.

    A l'origine, cet outils c'était en Delphi pour Delphi. Mais je n'ai pas hésité à réinvestir du temps lorsqu'il m'a fallu le redévelopper en .Net

    Exemple vécu

    Je garderais toujours à l'esprit une situation que j'ai vécu fin 1999 début 2000. Sur un projet, je travaillais sur des documents de requête hypothécaires de type cerfa. Il y avait plein de date dans ce projet. En phase test, mon client m'appel et me dit, "je ne peux pas saisir une date de naissance". Je lui demande "quelle date ?". Il me dit un truc du genre "janvier 1948". Je lui répond que ce n'est pas une date de naissance. Et c'est la qu'il m'explique que si. Que des personnes peuvent être nées dans des pays en guerre, dans des pays où il n'y a pas d'administration, avoir été abandonnées, que des erreurs d'enregistrement peuvent avoir été faites et que lorsque l'on fait une demande hypothécaire, elle doit être demandée telle qu'elle a été enregistrée. Il paraîtrait même que "15/13/1948" ça pourrait exister !!!

    Vous imaginez cela. Le cahier des charges n'avait pas mis en avant ce problème. Après analyse de tous les cas possibles, il s'est avéré qu'il fallait transformer tous les champs date de l'application et les mettre au format chaîne libre. Vous imaginez l'impacte ?

    Après avoir fait la modification sur la base de données, cela m'a demandé 5 minutes pour lancer mon assistant. L'interface s'est adaptée. J'ai eu quelques requêtes à modifier. En moins d'une heure mon programme de 600 000 lignes qui comprenait un Intranet, un site Web, et une application Minitel fonctionnait à nouveau.

    C'est vrai, cet exemple et quelque peu étonnant et c'est pour cela que je le relate car je pense qu'il peut marquer les esprits. Mais, il est si régulier que nous ayons à apporter des modifications mineurs sur nos bases. Modifications qui ont un impact sur nos codes.

    Conclusion

    Vos besoins ne vous obligeront peut être pas à aller si loin. Mais je vous encourage à prendre le temps. Lisez en profondeur la doc. Regardez des codes exemple sur le net pour voir comment un tel et un tel procède. Listez les avantages et inconvénients de chaque façon. Demandez vous quels sont les choix qui apportent le plus de maîtrise, quels sont les choix les plus linéaires, quels sont les choix les moins 'bricolage'.

    Puis lâchez vous. Imaginez vous un modèle. Faire un assistant n'oblige pas à l'intégrer dans Visual Studio. Un programme console générant des fichiers à la volée fait tout à fait l'affaire. Même sans utiliser Toad, il est tout à fait possible de se connecter sur une base et d'en analyser les tables de façon à produire du code de façon automatique et normalisée par rapport à un modèle que vous avez défini et imaginé. Sans mentir, moins d'une journée suffit bien souvent à ce genre de travail.

    Bon courage.
    Michaël LEBRETON - Developpeur / Formateur indépendant
    http://www.netkoders.com

  9. #9
    Membre régulier

    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    68
    Détails du profil
    Informations personnelles :
    Âge : 52
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Novembre 2007
    Messages : 68
    Points : 104
    Points
    104
    Par défaut D'un coté un peu plus technique
    Pour aborder la partie plus technique de la question :

    Imaginons une Table TEST contenant les champs ID, A, B et C ou ID serait la clé primaire.

    Avec les 4 requêtes suivantes ont peut presque tout faire sur la table.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    SELECT * FROM TEST
    INSERT INTO TEST (ID,A,B,C) VALUES (@ID,@A,@B,@C)
    UPDATE TEST SET A=@A, B=@B, B=@C WHERE ID=@ID
    DELETE FROM TEST WHERE ID=@ID
    NOTE : Le @ précède les noms des paramètres disponibles dans la collection Parameters de chaque objet Command.

    Dans la majorité des cas, seul la requête SELECT changera. On y ajoutera une clause WHERE, on fera des jointures sur des tables...

    On comprend donc le rôle du DataAdapter. Il dispose justement de quatre Commandes, une pour chacune des commandes SQL ci-dessus. Avec ses deux méthodes Fill et Update on peut tout faire. Il exploite tout seul les requêtes appropriées. Que demander de mieux ?

    Il ne serait donc pas difficile d'imaginer un automate qui à la lecture de la base de donnée écrirait dans un fichier le code des DataAdpater correspondant à chaque Table (surtout si il y a une grande quantité de tables, on est pas fainéant mais tout de même. En plus, cela systématise le travail. Alors quand la flemme a des avantages il ne faut pas s'en priver).

    Ensuite, le même automate pourrait écrire du code pour chaque table, implémenter les colonnes, retourner le DataAdapter de la table...

    Au final, il ne resterait plus qu'à implémenter sur chaque table des méthode de sélection, qui modifieraient la command SELECT en fonction de nos besoins.

    Certes, je simplifie, c'est à vous de voir le niveau d'intégration dont vous avez besoin. Bref, à vous d'imaginer.

    REMARQUE : En ASP.NET, vu que l'on ne préserve pas d'états et que l'on peut trouver maladroit de garder toute sorte de DataSet et de Table en mémoire, on trouve souvent plus avantageux d'écrire un modèle qui n'utilise pas le DataAdapter mais qui effectue en direct, en temps réel les requêtes sur la base de données.
    Michaël LEBRETON - Developpeur / Formateur indépendant
    http://www.netkoders.com

  10. #10
    Membre régulier

    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    68
    Détails du profil
    Informations personnelles :
    Âge : 52
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Novembre 2007
    Messages : 68
    Points : 104
    Points
    104
    Par défaut Pour tout le DataSet
    Au fait, mettre à jour tout un DataSet, ce n'est rien d'autre que mettre à jour toute les tables qu'il contient.

    Si on a travaillé sur un modèle ressemblant à celui que j'ai décrit ci dessus, on pourrait imaginer que chaque table dispose d'une méthode Update qui en interne ferait appel au DataAdpater correspondant à la table.

    Ainsi, mettre à jour tout un DataSet serait une simple itération appelant une simple méthode.

    C'est là que l'on se dit, pourquoi ne pas surcharger l'objet DataSet afin de l'adapter à nos besoins. C'est l'idée des DataSet fortement typés.
    Michaël LEBRETON - Developpeur / Formateur indépendant
    http://www.netkoders.com

  11. #11
    Membre averti Avatar de Contrec
    Homme Profil pro
    Inscrit en
    Mars 2005
    Messages
    597
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38

    Informations forums :
    Inscription : Mars 2005
    Messages : 597
    Points : 342
    Points
    342
    Par défaut
    Personnellement je travaille sur des DataSets fortement types. Toutes mes requetes SQl sont centralisees dans les xsd de Visual Studio et tout est cree a partir de l'assistant. Aucun code SQL ou connexion avec la base de donnees n'est ecrite en dur dans le code.
    Les avantages sont nombreux: Rapidite, facile d'utilisation, bien liste par table, gere les liens et contraintes.

    Un seul inconvenient est a signaler. Lorsque la structure d'une table change, il faut raffraichir le Dataset avec la nouvelle structure. Visual studio propose alors de mettre a jour toutes les requetes ecrites pour integrer ce changement. En pratique, Visual studio fait des erreurs en changeant les requetes SQL. Il faut donc revoir toutes les requetes afin de s'assurer a la fois que la nouvelle structure est integree mais aussi que Visual studio n'a pas re-ecrit des requetes avec des erreurs.

    Voila mon experience personnelle. Pour une application de gestion, les DataSet types et l'assistants de Visual studio suffisent largement et permettent de gagner beaucoup de temps.
    Contrec

  12. #12
    Nouveau membre du Club
    Inscrit en
    Novembre 2006
    Messages
    39
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 39
    Points : 26
    Points
    26
    Par défaut
    Merci a tous pour vos réponses, mais ca ne me convient pas, je rappelle que je travaille sur une base mysql, je suis donc obligé de passer par un driver (ici mysql connector pour .net), et je dois tout écrire, seulement ce qui me perturbe c'est que l'on puisse utiliser des command builder qui peuvent gérer de facon automatique les requetes, mais un objet dataadapter ne peut être lié qu'a une seule table à la fois, car il ne possede qu'une seule propriété selectCommand, insertCommand, deleteCommand, et updateCommand !!

    Donc, contrec, je ne peux pas utiliser l'assistant de visual studio, et mlebreton, l'outils toad dont tu me parles concerne uniquement les bases oracles ...

    Ma question est la suivante , comment implementer de manière intelligente son ou bien ses dataadapter, pour que le dataset qui contient les datatable correspondantes a mes tables puisse mettre a jour la base de donnée, et , ou , se rafraichir lorsque la base de donnée change, quand par exemple un autre utilisateur a fait des modifications sur celle ci .... ??
    N'existe t'il pas un exemple de ce genre de réalisation ? car les exemples que j'ai pu trouvé ne travaille que sur une seule table et sont souvent de fois très succint.

  13. #13
    Membre régulier

    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    68
    Détails du profil
    Informations personnelles :
    Âge : 52
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Novembre 2007
    Messages : 68
    Points : 104
    Points
    104
    Par défaut En ce qui concerne Toad
    Qu'il s'agisse de Toad ou de CaseStudio (sa version précédente), ces deux produits peuvent travailler avec la grande majorité des SGBD du marcher, dont MySql.

    Maintenant, comme je l'ai mentionné plus haut, un tel outil n'est pas INDISPENSABLE pour implémenter sa gestion des données. Ma remarque était d'ordre méthodologique. En effet, il est facile de produire du code pour 1 table, mais cela se complique quand il faut produire du code pour 20, 50, 100, 200 tables... Tout comme ont peut très bien avoir besoin d'implémenter plusieurs DataSet (on utilise pas toutes les tables de la base dans tous les process). Il est donc utile d'avoir ses propres outils qui implémentent notre propre logique. Ce besoin se fait particulièrement ressentir quand l'application peut se découper en métiers différents.
    Michaël LEBRETON - Developpeur / Formateur indépendant
    http://www.netkoders.com

  14. #14
    Membre régulier

    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    68
    Détails du profil
    Informations personnelles :
    Âge : 52
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Novembre 2007
    Messages : 68
    Points : 104
    Points
    104
    Par défaut Assistants, DataAdapter et DataSet...
    En ce qui concerne la connexion et la possibilité d'utiliser les assistants

    En ce qui concerne l'accès à MySql, cela ne devrait normalement faire aucune différence. Microsoft .Net s'appuie sur un modèle de fournisseurs et donc il suffit d'avoir un fournisseur approprié pour travailler sur MySql comme sur n'importe quel autre SGBD (vous parlez entre autre de ici mysql connector pour .net). Et dans ce cas, les assistants devraient être utilisables au même titre qu'avec une base SQL Serveur. Si cela ne fonctionne pas bien c'est sans doute qu'il faut trouver un meilleur fournisseur (tous les fournisseurs n'implémentent pas toutes les fonctionalités correctement). Si il n'y en a pas de disponibles, il suffit de se replier sur un fournisseur OLE DB pour MySql et utiliser une connexion OLE DB dans .Net (je sais que cela peut parraitre étonnant, mais cela ne sera pas forcément plus lent).

    En ce qui concerne les DataAdapter

    Il n'y a pas de secret. Si vous voulez travailler sur vos tables, il faudra tôt ou tard que vos requêtes SQL soient écrites quelques part, soit par un assistant, soit par vous même.

    Pour chaque tables, il faudra écrire 4 requête : SELECT, INSERT, UPDATE, DELETE, c'est incontournable (On peut parfois réduire ce nombre quand par exemple on n'a pas besoin de modifier les données ou de les supprimer).

    Une des méthodes de base mise à notre disposition consiste à utiliser le DataAdapter qui encapsule justement 4 objets Command pour chacune de ces requêtes et qui dispose de deux méthodes Fill et Update qui permetent en fait de faire à peu prês tout ce dont on a besoin sur une table.

    Donc, que ce soit en utilisant un assistant, que ce soit en utilisant un automate de production de code (voir mes commentaires sur Toad plus haut), ou que ce soit à la mimine, il faudra, dans la pluspart des cas un DataAdpater avec 4 Command SQL pour chaque table.

    Ainsi, pour remplir un DataSet, on utilisera les DataAspater des tables et leur méthode Fill. Pour mettre à jour un DataSet, on utilisera les même DataAdapter mais via leur méthode Update cette fois ci.
    Michaël LEBRETON - Developpeur / Formateur indépendant
    http://www.netkoders.com

  15. #15
    Membre actif
    Inscrit en
    Août 2006
    Messages
    381
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 381
    Points : 252
    Points
    252
    Par défaut
    Citation Envoyé par Contrec
    Personnellement je travaille sur des DataSets fortement types. Toutes mes requetes SQl sont centralisees dans les xsd de Visual Studio et tout est cree a partir de l'assistant. Aucun code SQL ou connexion avec la base de donnees n'est ecrite en dur dans le code.
    Les avantages sont nombreux: Rapidite, facile d'utilisation, bien liste par table, gere les liens et contraintes.
    Un gros inconvénient des dataset typés, c'est justement pour remplir plusieurs tables lié par une relation one to many avec une seule requête.
    Je m'explique, supposons que :
    - tu aies dans ta base une table Commande et une table DetailCommande
    - une des règles métiers est d'obtenir toutes les commandes non expédiées d'un client.
    Pour faire ça, tu ne peux pas te contenter d'une seule requête. Tu dois développer deux requêtes, une pour obtenir les commandes non expédiées d'un client et une autre pour obtenir les détails des commandes non expédiées d'un client.
    Quand tu as une grosse base avec plein de relations one to many, ça devient très vite ingérable.

    Autre problème avec le dataset typé et le tableadapter, c'est que tu ne peux pas faire une couche avec rien que tes objets métiers, ils sont dans la couche d'accès aux données.

    Bye

  16. #16
    Nouveau membre du Club
    Inscrit en
    Novembre 2006
    Messages
    39
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 39
    Points : 26
    Points
    26
    Par défaut
    Alors que proposes tu pilloutou ???

  17. #17
    Membre régulier

    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    68
    Détails du profil
    Informations personnelles :
    Âge : 52
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Novembre 2007
    Messages : 68
    Points : 104
    Points
    104
    Par défaut La conversation tourne en rond ?
    Je me fais peut être une idée, mais j'ai la sensation que la conversation tourne un peu en rond car de post en post on retrouve les mêmes idées.

    1) Soit on utilise les outils de génération mis à notre disposition par Visual Studio et on s'en contente, avec les avantages et les inconvénients que cela implique. Dans ce cas il faut bien garder à l'esprit que ces outils ont avant tout étés pensés pour répondre à des besoins d'architecture 3-tiers : l'intelligence est dans la base de données (généralement sous forme de procédures stockées ou de triggers). Ainsi, essayer de leur faire faire autre chose n'est pas des plus facile.

    2) Soit on utilise d'autres outils implémentant d'autres modèles de programmation. Il y en a de nombreux sur le marcher. La problématique consiste à trouver celui qui répond à nos besoins.

    3) Soit on fait tout à la main en implémentant ce que l'on veut. C'est puissant, on garde 100% de la maîtrise, mais c'est plus long et il faut de solides connaissances. On peut dans ce contexte créer ses propres outils pour systématiser sa démarche et gagner du temps (voir les posts précédents).

    MAIS DANS TOUS LES CAS IL N'Y A PAS DE SOLUTION MIRACLE. Si c'était le cas, un grand nombre d'informaticiens perdraient leur gagne pain.

    Petit état des lieux

    1) .Net est propose une architecture et un modèle de programmation ouvert permettant de travailler de façon uniforme avec quasi n'importe quel système d'information du marcher, dont les bases de données.

    2) Quand on travail avec des bases de données, on se retrouve confronté aux problèmes liés à l'utilisation des bases de données. C'est logique. Cela veut dire, lire, écrire, modifier, supprimer, mais aussi transaction, accès concurrentiels, verrouillage... En fait, c'est pas nouveau, c'est ainsi depuis que les bases de données existent.

    Ainsi, pour tout projet, il faut déterminer la façon dont on va travailler avec les données et le modèle d'accès que l'on va utiliser. Ce modèle d'accès sera différent en fonction de tout un nombre de contraintes très complexes :

    - L'architecture globale de l'application (par exemple, on n'utilise pas du tout les mêmes modèles pour les applications Windows que pour les application Web).
    - Le nombre d'utilisateurs potentiels.
    - Les besoins métier.
    - Les besoins multi portail.
    - Les besoins d'évolutivité.
    - L'architecture machines.
    - La sécurité.
    - Les contraintes technologiques.
    - ...

    Bref, c'est un métier en soit que de répondre à cette question. Si vous ne savez pas y répondre, je ne voit que les solutions suivantes :

    1) Cherchez une solution générique répondant à vos besoins.

    2) Si votre projet n'est de d'une trop grande envergure, faire comme vous pouvez en tenant compte des conseils donnés dans les posts précédents. Cela donnera ce que cela donnera. Dans ce cas, modélisez votre solution et n'hésitez pas à nous soumettre votre modèle afin que nous le commentions.

    3) Acquérir les compétences nécessaires (cela passera par de la formation car dans ce domaine il est important d'être confronté à différents retours d'expériences. Il y a aussi d'excellente référence dans la presse informatique : Professional ASP.NET 2.0 Databases (Wrox Professional Guides), Beginning C# 2005 Databases, et bien d'autres).

    4) Faire appel à un architecte ou au minimum faire auditer votre situation.

    Et je ne voudrais pas vous faire peur, mais vous n'êtes pas au bout de vos surprises. Vous verrez qu'ensuite, quand on utilise des contrôles comme le GridView ou autre, là encore on ne peut pas faire ce que l'ont veut. Bien que très puissants, ces contrôles ont étés imaginés pour fonctionner dans un contexte architectural précis.

    Ce qui est incontournable

    Quand on construit une maison, il faut choisir les matériaux. Il en sera de même d'une solution informatique. Il y a des matériaux incontournables et d'autres dont on peut se passer.

    Par exemple, on peut tout à fait se passer de DataSet, DataTable et de DataAdapter pour travailler sur les données. En revanche, il semble plus difficile de se passer d'une connexion ou des 4 requêtes SQL de base.

    Pour que la discussion avance

    Nous sommes face à une question du genre : "comment construit-on une maison ?". Il y a une infinité de réponses à cette question. Tout ce que l'on peut répondre dans ce cas c'est vous orienter en vous expliquant qu'il y a les maisons en bois, les maisons en briques, les toits ardoise, les toits tuiles, les chalets, les pavillons, les cottages, les châteaux... Mais que peut on vous répondre de plus. Votre question restera : "oui mais, comment construit-on une maison ?".

    Il faudrait donc transformer votre demande de la façon suivante : "voici les besoins de ma famille, pour y répondre je compte faire ma maison de telle et telle façon, qu'en pensez-vous". Et là, nous serons à même de vous donner des conseils, de vous faire voir les avantages et les inconvénients de votre projet. Vous pourrez alors le corriger, le faire évoluer.
    Michaël LEBRETON - Developpeur / Formateur indépendant
    http://www.netkoders.com

  18. #18
    Expert éminent Avatar de Graffito
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    5 993
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 993
    Points : 7 903
    Points
    7 903
    Par défaut
    Ok , d'accord, mais alors comment mapper les tables ??? existe t'il une solution qui pourrait faire ca automatiquement a partir du shéma de la base de donnée, en reprenant toutes les relations de cle etrangères existantes dans la base ??
    C'est cette solution que nous utilisons : génération automatique des commandes SQL du dataAdapter d'une table particulière à partir de la structure de la table, mais sans gérer les relations.
    Comme on ne touche plus à cette bibli de base, il me semble que la méthode qu'on utilise pour obtenir la structure consiste au chargement d'un enregistrement sans clause WHERE.
    " Le croquemitaine ! Aaaaaah ! Où ça ? " ©Homer Simpson

  19. #19
    Nouveau membre du Club
    Inscrit en
    Novembre 2006
    Messages
    39
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 39
    Points : 26
    Points
    26
    Par défaut
    Ca m'intéresse ça, comment tu procède grafitto ??

    J'ai vu que je peux m'en sortir a l'aide des commandBuilder, je pense que je vais continuer mes recherches dans ce sens ... La seule chose qui me trouble c'est que je ne vois comment gérer des relations multiples avec les dataTables, car prenons un exemple :

    J'ai une table 'adherent' qui contient les champs 'id_ville' et 'id_profession', avec donc une table 'ville' et une table 'profession'
    Ma table 'adherent' si je la bind sur un dataGrid, les champs id_ville' et 'id_profession' afficheront un index.
    Pour le moment la solution pour que ca affiche le nom de la ville et la profession, je dois faire des jointures dans une requete que je met moi meme , mais je ne sais si cela va m'empecher par la suite pour actualiser ma base via la methode update du dataadapter, car j'utilise alors un shéma qui est différent de celui de mes tables. Ou bien je dois écrire chaque requete, pour chaque opération. Ce qui risque d'être extrement lourd. Or, sur des formulaires de modifications, doit on actualiser tous les champs si on ne change qu'une seule information ??!!
    Mais si je genere mes datatables via le dataadapter, le shéma va rester conforme dans le dataset , mais la je ne sais pas si il est possible de creer une vue personnalisé à partir de mes datables, et ensuite créer les contraintes pour que les bonnes datatables soient mises à jour quand on effectue des modifications dans la vue.??

    En fait j'ai des doutes pour les deux méthodes que je connais et c'est pour ca que ne n'avance plus, j'aimerais ne pas foncer betement dans le mur si j'ai mal compris quelquechose.

    mlebreton, j'aprécie ce que vous dites mais ca ne m'aide pas enormement, car ca ne souleve pas mes doutes .... Mais je y arriverai !!!

    ps : je joins une partie du diagramme de ma base pour mieux visualiser le projet.
    Images attachées Images attachées  

  20. #20
    Expert éminent Avatar de Graffito
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    5 993
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 993
    Points : 7 903
    Points
    7 903
    Par défaut
    Bonjour,

    Le bout de code utilisé pour info.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    ==============================================  
    LECTURE DE LA STRUCTURE DE LA TABLE
    ==============================================  
    try
                {
                  string olebcommandstr = "";
                  switch (database.DbType)
                  {
                    case SxSysDatabase.DatabaseType.MSACCESS_OleDB :
                      olebcommandstr = "SELECT TOP 1 * FROM "+tablename; break;
                    case SxSysDatabase.DatabaseType.MYSQL_OleDB :
                      olebcommandstr = "SELECT * FROM "+tablename+" LIMIT 0,1"; break;
                  }
                  OleDbCommand SelectCommand = new OleDbCommand(olebcommandstr,(OleDbConnection)database.DbCnx);
                  OleDbDataAdapter adapter = new OleDbDataAdapter();
                  adapter.SelectCommand = SelectCommand;
                  System.Data.DataSet dataSet = new System.Data.DataSet() ;
                  adapter.Fill(dataSet);
     
     
    ==============================================  
    CONSTRUCTION DES COMMANDES SQL DES DATA ADAPTER
    ==============================================  
     
               try
                {
                  // Build Ole types table
                  OleDbType[] oletypes = new OleDbType[Columns.Count];
                  for (int i=0;i<Columns.Count;i++) GetOleDbType(Columns[i],out oletypes[i]); // NB: types verified in Init()
                  // Create SelectCommand ============================================================
                  where = where.Trim();
                  string sortby = "";
                  string querystr = "SELECT * FROM "+TableName;
                  if (where.Length>0) querystr += " WHERE "+where;
                  if ((Object)primarykey!=null && primarykey.Count>0)
                    for (int i=0;i<primarykey.Count;i++)
                    {
                      sortby += primarykey[i];
                      if (i<primarykey.Count-1) sortby += ",";
                    }
                  if (sortby.Length>0) querystr += " ORDER BY "+sortby;
                  OleDbCommand SelectCommand = new OleDbCommand(querystr, (OleDbConnection)DataBase.DbCnx);
                  adapter = new OleDbDataAdapter();
                  ((OleDbDataAdapter)adapter).SelectCommand = SelectCommand;
                  // Create InsertCommand ==============================================================
                  ((OleDbDataAdapter)adapter).InsertCommand = new System.Data.OleDb.OleDbCommand();
                  ((OleDbDataAdapter)adapter).InsertCommand.Connection = (OleDbConnection)DataBase.DbCnx;
                  string fieldsnames="",fieldvalues="";
                  for (int i=0;i<Columns.Count;i++)
                  {
                    fieldsnames += ""+Columns[i].ColumnName+""; fieldvalues += "?";
                    if (i<Columns.Count-1) { fieldsnames += ","; fieldvalues += ","; }
                    ((OleDbDataAdapter)adapter).InsertCommand.Parameters.Add
                      (new OleDbParameter
                            (Columns[i].ColumnName,oletypes[i],0,ParameterDirection.Input,((byte)(0)),((byte)(0)),
                             Columns[i].ColumnName,System.Data.DataRowVersion.Current,false,null));
                  }
                  ((OleDbDataAdapter)adapter).InsertCommand.CommandText = 
                          @"INSERT INTO "+TableName+" ("+fieldsnames+") VALUES ("+fieldvalues+")";
                  ((OleDbDataAdapter)adapter).InsertCommand.CommandType = System.Data.CommandType.Text;
                  // Create UpdateCommand ==============================================================
                  ((OleDbDataAdapter)adapter).UpdateCommand = new System.Data.OleDb.OleDbCommand();
                  ((OleDbDataAdapter)adapter).UpdateCommand.Connection = (OleDbConnection)DataBase.DbCnx;
                  string newfields="",oldfields=""; 
                  for (int i=0;i<Columns.Count;i++)
                  {
                    newfields += ""+Columns[i].ColumnName+"=?"; 
                    oldfields += "(("+Columns[i].ColumnName+"=?) OR (("+Columns[i].ColumnName+" IS NULL)AND(? IS NULL)))";
                    if (i<Columns.Count-1) { newfields += ","; oldfields += " AND "; }
                    ((OleDbDataAdapter)adapter).UpdateCommand.Parameters.Add(new OleDbParameter
                      (Columns[i].ColumnName,oletypes[i],0,ParameterDirection.Input,((byte)(0)),((byte)(0)),
                       Columns[i].ColumnName,System.Data.DataRowVersion.Current,false,null));
                  }
                  for (int i=0;i<Columns.Count;i++) for(int j=1;j<=2;j++)
                  {
                    ((OleDbDataAdapter)adapter).UpdateCommand.Parameters.Add(new OleDbParameter 
                     ("Original_"+j+"_"+Columns[i].ColumnName,oletypes[i],0,ParameterDirection.Input,((byte)(0)),((byte)(0)),
                      Columns[i].ColumnName,System.Data.DataRowVersion.Original,false,null));
                  }
                  ((OleDbDataAdapter)adapter).UpdateCommand.CommandText = 
                          @"UPDATE "+TableName+" SET "+newfields+" WHERE ("+oldfields+")";
                  ((OleDbDataAdapter)adapter).UpdateCommand.CommandType = System.Data.CommandType.Text;
                  // Create DeleteCommand ==============================================================
                  ((OleDbDataAdapter)adapter).DeleteCommand = new System.Data.OleDb.OleDbCommand();
                  ((OleDbDataAdapter)adapter).DeleteCommand.Connection = (OleDbConnection)DataBase.DbCnx;
                  fieldsnames="";
                  for (int i=0;i<Columns.Count;i++)
                  {
                    fieldsnames += "(("+Columns[i].ColumnName+"=?) OR (("+Columns[i].ColumnName+" IS NULL)AND(? IS NULL)))";
                    if (i<Columns.Count-1) fieldsnames += "AND";
                    for(int j=1;j<=2;j++)
                      ((OleDbDataAdapter)adapter).DeleteCommand.Parameters.Add
                        (new OleDbParameter
                        ("Original"+j+"_"+Columns[i].ColumnName,oletypes[i],0,ParameterDirection.Input,((byte)(0)),((byte)(0)),
                          Columns[i].ColumnName,System.Data.DataRowVersion.Original,false,null));
                  }
                  ((OleDbDataAdapter)adapter).DeleteCommand.CommandText = 
                    @"DELETE FROM "+TableName+" WHERE ("+fieldsnames+")";
                  ((OleDbDataAdapter)adapter).DeleteCommand.CommandType = System.Data.CommandType.Text;
                }
                catch (Exception e)
                { 
                  SxStrings.AddStringToTsl("Can not read from table "+TableName+"(Where="+where+") : '"+e.Message+"'",errors); 
                  result = false;
                }
                break;
              default :
                result = false;
                SxStrings.AddStringToTsl("Not processed table type!",errors); 
                break;
    " Le croquemitaine ! Aaaaaah ! Où ça ? " ©Homer Simpson

Discussions similaires

  1. DataAdapter et DataSet
    Par Nixar dans le forum ASP.NET
    Réponses: 2
    Dernier message: 20/07/2008, 19h56
  2. probleme avec dataadapter et dataset.
    Par HULK dans le forum ASP.NET
    Réponses: 22
    Dernier message: 11/06/2007, 09h08
  3. dataAdapter Fill (dataSet,"tel");
    Par lion000 dans le forum Windows Forms
    Réponses: 1
    Dernier message: 05/05/2007, 18h25
  4. [C#] DataAdapter et DataSet
    Par diaboloche dans le forum Accès aux données
    Réponses: 2
    Dernier message: 17/02/2007, 17h12

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo