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 :

Imbrication de ForEach propre ou pas ?


Sujet :

C#

  1. #1
    Membre habitué
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Octobre 2011
    Messages
    255
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2011
    Messages : 255
    Points : 193
    Points
    193
    Par défaut Imbrication de ForEach propre ou pas ?
    Bonjour à tous,

    Je suis entrain de développer une appli de gestion de magasin.

    J'ai plusieurs table ( produit,commande,ligne de commande, client, fournisseur ...)

    Pour chaque table j'ai créer une fonction lister, avec comme paramètre l'id de la table.

    J'ai un DataGridView dans mon From qui liste les info de chaque commandes.

    Dans cette liste je souhaite affiché des info de la table commande, ligne de commande, produit et client.

    J'ai donc utiliser une imbrication de foreach pour ajouter a ma DataTable les différentes information.

    Ensuite ce DataTable est ajouter a la propriété DataSource du DataGridView.

    Mais plus je regarde ce bout de code, plus je me dit que cette méthode est très sale.

    Une imbrication de forEach doit consommé une grande quantité de ressources. ( pour l'instant je m'en rend pas compte vue que mes tables contienne quelque lignes )

    J'ai penser a créer une fonction spéciale qui listerai avec comme paramètre une requête.

    Cette requête serai bourré de jointure et niveau performance je sais pas sa pourrai être mieux.

    Donc je me tourne vers vous pour avoir votre avis d'expert et connaître les bonne pratique a adopté dans cette situation.

    Voici le code :

    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
     
     private void Commande_Load(object sender, EventArgs e)
            {
                DataTable CommandeTb = new DataTable();
                CommandeTb.Columns.Add("idcom");
                CommandeTb.Columns.Add("idclient");
                CommandeTb.Columns.Add("datecom");
                CommandeTb.Columns.Add("etat");
                CommandeTb.Columns.Add("nom");
                CommandeTb.Columns.Add("idprod");
                CommandeTb.Columns.Add("quantite");
                CommandeTb.Columns.Add("nomProduit");
                CommandeTb.Columns.Add("description");
     
                foreach (TraiteurLibrairie.Commande DataCommande in Gestion.ListerCommande(0))
                {
                    foreach (Client DataClient in Gestion.ListerClient(DataCommande.idclient))
                    {
                        foreach (Ligne DataLigne in Gestion.ListerLigne(DataCommande.idcom))
                        {
     
                           foreach (Produit DataProduit in Gestion.ListerProduit(DataLigne.idprod))
                           {
                               CommandeTb.Rows.Add(DataCommande.idcom, DataCommande.idclient, DataCommande.datecom,DataCommande.etat, DataClient.nom, DataLigne.idprod, DataLigne.quantite, DataProduit.nom, DataProduit.description);
     
                           }
                        }
                    }
                }
     
     
                this.dataGridViewCommande.DataSource = CommandeTb;
                this.dataGridViewCommande.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
     
                this.toolStripStatusLabel1.Text = "Gestion des commandes";
     
            }
    Merci a vous pour vos remarque et critique
    Life myLife = new Life ("eat","sleep","code");

  2. #2
    Expert confirmé Avatar de DonQuiche
    Inscrit en
    Septembre 2010
    Messages
    2 741
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 2 741
    Points : 5 485
    Points
    5 485
    Par défaut
    Sur un cas de ce genre, une unique requête apporterait tout de même un gain significatif. Car même si les deux méthodes reviennent de toute façon à faire des jointures, le fait d'avoir une requête au lieu de cent permet d'économiser sur le parsing de la requête (réalisée une seule fois), sur la charge réseau (et la latence du point de vue du client), sur la gestion de la concurrence, etc... Et comme en plus tu peux sans doute (selon ton SGBD) te débrouiller pour combiner l'insertion et la sélection en une seule requête, tu éviteras de rapatrier les données nécessaires vers le client, d'autant que tes méthodes actuelles rapatrient sans doute beaucoup de données inutiles. Enfin une unique requête fournit au SGBD davantage d'opportunités d'optimisation.

    Cela étant dit, il y a bien un seul client par commande ? Sinon ListerLigne pourrait déjà être mis en cache avant l'appel à ListerClient.

  3. #3
    Membre habitué
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Octobre 2011
    Messages
    255
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2011
    Messages : 255
    Points : 193
    Points
    193
    Par défaut
    Merci DonQuiche pour ta réponse et tes explications.

    Effectivement je me douté que niveau perf, ce n'était pas la joie.
    Je vais donc faire une fonction avec une requête comme paremètre. Même si il est vrai, je n'aime pas trop avoir des requête dans mon code finale. Je préfère les mettre dans mes class Technique.

    Encore merci pour tes conseils.
    Life myLife = new Life ("eat","sleep","code");

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. tag c:foreach ne marche pas
    Par daydream123 dans le forum Taglibs
    Réponses: 1
    Dernier message: 22/03/2012, 16h10
  2. [PHP 5.3] Imbrication de foreach
    Par rps8484a dans le forum Langage
    Réponses: 5
    Dernier message: 01/11/2011, 11h16
  3. propre ou pas propre ?
    Par Invité2 dans le forum Langage
    Réponses: 16
    Dernier message: 31/01/2011, 17h39
  4. foreach ne prend pas en compte
    Par ekremyilmaz dans le forum Servlets/JSP
    Réponses: 1
    Dernier message: 09/07/2010, 11h33
  5. [PHP-JS] foreach qui fonctionne pas
    Par tiger63 dans le forum Langage
    Réponses: 4
    Dernier message: 06/04/2007, 15h49

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