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

VB.NET Discussion :

Optimisation de TableAdapter.Fill() dans une boucle


Sujet :

VB.NET

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Août 2009
    Messages
    140
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2009
    Messages : 140
    Points : 37
    Points
    37
    Par défaut Optimisation de TableAdapter.Fill() dans une boucle
    Bonjour

    Actuellement, je remplit les DataTables de mon DataSet via la méthode .Fill() des Table Adapters associés à la connection vers une BDD Access.
    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
            Me.FoodTableAdapter.Fill(Me.DataSet.Food)
            Me.WeaponTableAdapter.Fill(Me.DataSet.Weapon)
            Me.AmmoTableAdapter.Fill(Me.DataSet.Ammo)
            Me.RangedTableAdapter.Fill(Me.DataSet.Ranged)
            Me.HeadTableAdapter.Fill(Me.DataSet.Head)
            Me.HP_ScalingTableAdapter.Fill(Me.DataSet.HP_Scaling)
            Me.NeckTableAdapter.Fill(Me.DataSet.Neck)
            Me.HandsTableAdapter.Fill(Me.DataSet.Hands)
            Me.BodyTableAdapter.Fill(Me.DataSet.Body)
            Me.RingTableAdapter.Fill(Me.DataSet.Ring)
            Me.EarTableAdapter.Fill(Me.DataSet.Ear)
            Me.WaistTableAdapter.Fill(Me.DataSet.Waist)
            Me.BackTableAdapter.Fill(Me.DataSet.Back)
            Me.LegsTableAdapter.Fill(Me.DataSet.Legs)
            Me.FeetTableAdapter.Fill(Me.DataSet.Feet)
            Me.Damage_TypesTableAdapter.Fill(Me.DataSet.Damage_Types)
            Me.Skills_ListTableAdapter.Fill(Me.DataSet.Skills_List)
            Me.Jobs_ListTableAdapter.Fill(Me.DataSet.Jobs_List)
            Me.BLU_SpellsTableAdapter.Fill(Me.DataSet.BLU_Spells)
            Me.BLU_Job_TraitsTableAdapter.Fill(Me.DataSet.BLU_Job_Traits)
            Me.AreasTableAdapter.Fill(Me.DataSet.Areas)
            Me.EnemiesTableAdapter.Fill(Me.DataSet.Enemies)
            Me.BuffsTableAdapter.Fill(Me.DataSet.Buffs)
            Me.EnfeebsTableAdapter.Fill(Me.DataSet.Enfeebs)
            Me.Job_AbilitiesTableAdapter.Fill(Me.DataSet.Job_Abilities)
            Me.Job_StatSkill_GradesTableAdapter.Fill(Me.DataSet.Job_StatSkill_Grades)
            Me.Job_TraitsTableAdapter.Fill(Me.DataSet.Job_Traits)
            Me.Mob_DataTableAdapter.Fill(Me.DataSet.Mob_Data)
            Me.Race_Stat_GradesTableAdapter.Fill(Me.DataSet.Race_Stat_Grades)
            Me.Skill_CapsTableAdapter.Fill(Me.DataSet.Skill_Caps)
            Me.Stat_ScalingTableAdapter.Fill(Me.DataSet.Stat_Scaling)
            Me.Stats_ListTableAdapter.Fill(Me.DataSet.Stats_List)
            Me.WS_AvailabilityTableAdapter.Fill(Me.DataSet.WS_Availability)
            Me.WS_TableTableAdapter.Fill(Me.DataSet.WS_Table)
    Comme on le voit ce code est bien répétitif... J'essaie donc de réduire toutes ces lignes en une seule boucle dans le genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
       For Each dt As DataTable In Me.DataSet.Tables
            For Each ta In DataSetTableAdapters ' cet espace de noms contient exactement tous les noms de mes TableAdapters, mais ne peut pas être utilisé après "In"...
                 If Replace(ta.ToString, "TableAdapter", "") = dt.ToString Then
                     ta.Fill(dt)
                 End If
            Next
       Next
    ...mais je n'y arrive pas.

    ou encore dans le sens inverse du code suivant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
            If Me.DataSet.HasChanges Then
                'Appliquer les changements dans la base de données
                Me.TableAdapterManager.UpdateAll(Me.DataSet)
            End If
    Malheureusement la méthode .FillAll() n'existe pas...

    Quelqu'un saurait-il la bonne syntaxe à employer ? Merci.

  2. #2
    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
    Le problème est d'associer à chaque table un DataAdapter unique.
    Or , en théorie, on peut utiliser plusieurs DataAdapter différents pour une même table.

    On ne peut pas résoudre le problème sans créer les objets ou tableaux permettant une bijection entre DataTable et DataAdapter.

    Edit : Peut-être le TableAdapterManager permet-il de le faire, mais je ne connais pas cette classe.
    " Le croquemitaine ! Aaaaaah ! Où ça ? " ©Homer Simpson

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Août 2009
    Messages
    140
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2009
    Messages : 140
    Points : 37
    Points
    37
    Par défaut
    Ok mais dans mon cas, les DataAdapters existent déjà, je pense ont dû etre créés automatiquement par le Designer lorsque j'ai fait ma connection. Ils commencent tous par le nom de la DataTable puis concaténés avec "TableAdapter".
    Je veux juste réutiliser les mêmes noms... en simplifiant dans une boucle plutôt que d'écrire 20 lignes de code.

    En fait, je me demande même pourquoi le designer ne m'a pas fait ces Fill automatiquement (pareil pour le UpdateAll) ?

  4. #4
    Membre éprouvé
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    665
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 665
    Points : 1 161
    Points
    1 161
    Par défaut
    Bonjour,
    et ça (non testé) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
            For Each ta In DataSetTableAdapters
                Dim dt As DataTable
                Replace(ta.ToString, "TableAdapter", "") = dt.ToString
                ta.Fill(Me.dataset.dt)
            Next

  5. #5
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Août 2009
    Messages
    140
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2009
    Messages : 140
    Points : 37
    Points
    37
    Par défaut
    Citation Envoyé par chrismonoye Voir le message
    Bonjour,
    et ça (non testé) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
            For Each ta In DataSetTableAdapters
                Dim dt As DataTable
                Replace(ta.ToString, "TableAdapter", "") = dt.ToString
                ta.Fill(Me.dataset.dt)
            Next
    Bonjour Chris et merci pour ta proposition, mais, comme je l'avais déjà précisé dans le commentaire du code posté, "DataSetTableAdapters" n'est pas une collection, mais un Espace de noms. Ce qui signifie syntaxiquement qu'il est inutilisable tel quel...
    Néanmoins j'ai quand même copié ta proposition et là erreur :
    DataSetTableAdapters est un espace de noms et ne peut être utilisé comme expression.

  6. #6
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Août 2009
    Messages
    140
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2009
    Messages : 140
    Points : 37
    Points
    37
    Par défaut
    J'ai trouvé une autre syntaxe :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
            For Each dt As DataTable In Me.DataSet.Tables
                For Each ta As Data.IDataAdapter In Me.TableAdapterManager.Container.Components.OfType(Of Data.IDataAdapter)()
                    If Replace(ta.ToString, "TableAdapter", "") = dt.ToString Then
                        ta.Fill(dt)
                    End If
                Next
            Next
    Mais cette fois, ce n'est plus le For each qui flanche, mais la variable "dt" du Fill(). Normalement il faut y mettre une DataTable, mais l'erreur est :
    Une valeur de type 'System.Data.DataTable' ne peut pas être convertie en 'System.Data.DataSet'.

  7. #7
    Expert confirmé
    Inscrit en
    Avril 2008
    Messages
    2 564
    Détails du profil
    Informations personnelles :
    Âge : 64

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 564
    Points : 4 441
    Points
    4 441
    Par défaut remplir les datatables avec fill
    bonjour,masmunai
    pourquoi remplir les datables ,puisque à l'insertion il ya une creation d'une instance de datatable et d'un tableadapter et invocation d'une methode fill.

    alors il y a 2 cas de figure:

    1/ tu veux afficher tes tables
    -tu rajoute un controle lie au donnes et le designer te demande la source de donne et il cree un bindingsource automatique.
    -a l'execution il te remplit automatiquement le controle lie(il execute le fill behind the scene,derriere les coulisses pour parler en francais).
    - la synchronisation des donnees entre les controles est egalement acquise(behind the scene,TableAdapterManager est à l'oeuvre).

    2/ tu veux associer une table à autre chose qu'un controle visuel mettons:
    - une liste de champ (NomClient,NomProduit,NumeroCommande),tu n'as pas besoin d'un tableadapter,tu auras plus tot besoin d'une liste à remplir en parcourant la datatable et en ajoutant le champ cible .
    Dans un controle lie au donne il suffit de faire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    datagridview1.datasource=listeNomClient
    -une classe mappe sur un ou plusieurs champs d'une datatable ,c'est pareil tu fais une boucle sur la datatable et tu instancie ta classe ,tu remplis chaque champ de la classe et tu associe une liste qui gere la classe.

    exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    public class PProduit 'classe mappe sur datatable Produit
    public listePProduit as list(of PProduit) ' liste qui gere la classe
    Dans un controle lie au donne il suffit de faire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    datagridview1.datasource= listePProduit
    Il affichera dans la datagridview les champs mappes.
    Donc les Fill sont gratuits,c'est le traitement et la synchronisation entre les datagridview qu'il faut faire par code avec(il n' y a plus de TableAdapterManager helas).


    tout avantage se paye (l'inconvenient de l'avantage) ,c'est la loi de notre maratre nature.
    etre ou ne pas etre telle est la question...
    bon code....

  8. #8
    Membre chevronné
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2009
    Messages
    1 048
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2009
    Messages : 1 048
    Points : 2 201
    Points
    2 201
    Par défaut
    Ce que tu veux faire ne s'appelle pas selon moi une optimisation (ça ne va pas faire avancer ton code plus vite, peut être même l'inverse (ajout temps de gestion de boucle)). De plus il me semble que VisualStudio ajoute ces instruction automatiquement. Si tu veux gagner de la lisbilité à l'écran en cachant ceci il y a d'autre techniques propre à l'IDE.

    Ce qui est une optimisation:

    - D'appeller le fill des tableadapters qui sont utiles dans le context. (Ne charger que les tables que l'on va effectivement utilisé dans le dataset). Simple à mettre en place, provoque parfois des surprises quand on coupe trop large (mais pourquoi ma requête Linq renvoie rien....)

    - De "surcharger" la méthode fill des tableadapters afin de ne charger que les enregistrement d'une table nécessaire à l'application, à l'aide de paramètres. Plus compliqué à mettre en place, mieux vaut vraiement prendre un temp de réflexion avant de se lancer la dedans.

Discussions similaires

  1. [MySQL] Requête SQL dans une boucle : optimisation
    Par guiom056 dans le forum PHP & Base de données
    Réponses: 2
    Dernier message: 10/05/2010, 12h09
  2. optimiser une boucle while imbriquer dans une boucle for
    Par bakaratoun dans le forum MATLAB
    Réponses: 0
    Dernier message: 28/01/2010, 15h35
  3. swf dans une boucle asp
    Par Chucky69 dans le forum Flash
    Réponses: 11
    Dernier message: 10/02/2004, 17h07
  4. [Vb.net] Indexé un objet crée dans une boucle
    Par picpic dans le forum Windows Forms
    Réponses: 10
    Dernier message: 17/12/2003, 14h37
  5. Pause dans une boucle
    Par HT dans le forum Langage
    Réponses: 4
    Dernier message: 03/06/2003, 08h52

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