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 :

Retourner un dictionnaire depuis une requête Linq


Sujet :

C#

  1. #1
    Expert confirmé

    Homme Profil pro
    Développeur .NET
    Inscrit en
    Novembre 2010
    Messages
    2 066
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Novembre 2010
    Messages : 2 066
    Points : 4 233
    Points
    4 233
    Par défaut Retourner un dictionnaire depuis une requête Linq
    Bonjour,
    je fais quelque essais pour rendre une méthode "générique" (je ne sais pas si c'est le bon terme ici).
    J'ai donc une classe personne (Nom,Prenom,Pays,Age), une classe PersonneS qui est une List<Personne>, j'ai créer une méthode qui me retourne sous forme d'un Dictionary<string, int> le nombre de personne pour une propriété donnée ce qui m'évite de créer une méthode pour chaque propriété:
    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
     public class Personnes : List<Personne>
        {
     
            public Personnes RecupererTous()
            {
                return new DB().RecupererPersonne();
            }
     
            public Dictionary<string, int> PersonnePar(string nomPropriete)
            {
                Dictionary<string, int> personnePar = new Dictionary<string, int>();
                try
                {
                    if (this == null || this.Count == 0)
                    {
                        this.AddRange(RecupererTous());
                    }
     
                    this.GroupBy(p => p.GetType().GetProperty(nomPropriete).GetValue(p, null)).Select(p => new
                    {
                        Key = p.Key.ToString(),
                        Value = p.Count()
                    })
                    .ToList()
                    .ForEach(t => personnePar.Add(t.Key, t.Value));
                    // this.ForEach(p => NombreParPropriete(p, personneParPays, nomPropriete));
     
     
                }
                catch (Exception ex)
                {
                    throw ex;
                }
                return personnePar;
            }
    j'aimerais déjà pouvoir directement retourner un Dictionary<string, int> avec ma requête linq et rendre ce Dictionnaire un peu plus générique par la suite (avoir un Dictionary<Tkey, int> dans le cas ou la propriété n'est pas forcément une string).

    Si quelqu'un aurait une piste pour moi Merci.

    (C'est un petit exercice personnel qui ne rentre pas dans le cadre d'un projet)

  2. #2
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 753
    Points
    39 753
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
            public Dictionary<TProperty, int> PersonnePar<TProperty>(Func<Person, TProperty> selector)
            {
                    if (this.Count == 0)
                    {
                        this.AddRange(RecupererTous());
                    }
     
                    return this.GroupBy(selector).ToDictionary(g => g.Key, g => g.Count());
            }
    Plusieurs remarques sur ton code d'origine :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if (this == null || this.Count == 0)
    C'est impossible, this ne peut jamais être null...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
                try
                {
                    ...
                }
                catch (Exception ex)
                {
                    throw ex;
                }
    A quoi ça sert de faire un try/catch si c'est pour relancer aussitôt l'exception sans rien faire de plus ? Laisse l'exception remonter normalement...
    En plus, en faisant throw ex, tu perds la pile d'origine de l'exception, il faut faire throw tout court.

    p.GetType().GetProperty(nomPropriete).GetValue(p, null)
    Utiliser la réflexion comme ça est terriblement lent... Il vaut mieux utiliser un delegate qui va se charger de récupérer la propriété. La méthode que j'ai écrite s'utilise comme ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    var personnesParAge = personnes.PersonnePar(p => p.Age);
    En plus ça a l'avantage que tu ne peux pas te tromper en écrivant le nom de la propriété, car le compilateur vérifie

  3. #3
    Expert confirmé

    Homme Profil pro
    Développeur .NET
    Inscrit en
    Novembre 2010
    Messages
    2 066
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Novembre 2010
    Messages : 2 066
    Points : 4 233
    Points
    4 233
    Par défaut
    merci TomLev certaine chose était présente parce que la méthode était complètement différente à l'origine, faut que j'approfondisse mes connaissances au niveau des delegates et de leur utilisation (j'ai beau lire des tutos, leur utilisation m'échappe toujours pour autant)

  4. #4
    Rédacteur
    Avatar de Nathanael Marchand
    Homme Profil pro
    Expert .Net So@t
    Inscrit en
    Octobre 2008
    Messages
    3 615
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Expert .Net So@t
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2008
    Messages : 3 615
    Points : 8 082
    Points
    8 082
    Par défaut
    Je suis parti manger du coup tomlev est passé entre temps.
    J'ai donc une réponse qui ressemble:

    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
    void Main()
    {
    	var list = new List<Personne>
    	{
    		new Personne{ Nom = "Lajoie", Prenom = "Toto", Age = 10 },
    		new Personne{ Nom = "Lajoie", Prenom = "Bobby", Age = 20 },
    	};
     
    	CountByKey(list, p=>p.Nom).Dump();
    	CountByKey(list, p=>p.Prenom).Dump();
    	CountByKey(list, p=>p.Age).Dump();
     
    	CountByKey<Personne,int>(list, "Age").Dump();
    	CountByKey<Personne,String>(list, "Prenom").Dump();
    }
     
    Dictionary<TProp,int> CountByKey<TObj,TProp>(List<TObj> objects, Func<TObj,TProp> selector)
    {
    	return objects.GroupBy(o => selector(o)).ToDictionary (o => o.Key,o=>o.Count());
    }
     
    Dictionary<TProp,int> CountByKey<TObj,TProp>(List<TObj> objects, string property)
    {
    	var parameter = Expression.Parameter(typeof(TObj),"o");
    	var func = Expression.Lambda<Func<TObj,TProp>>(Expression.Property(parameter, property),parameter).Compile();
    	return CountByKey(objects, func);
    }
    Le CountByKey avec String est totalement gadget cela dit, c'était juste pour m'amuser je le trouve pas propre

  5. #5
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 753
    Points
    39 753
    Par défaut
    Citation Envoyé par Nathanael Marchand Voir le message
    encore un fan de LinqPad

  6. #6
    Expert confirmé

    Homme Profil pro
    Développeur .NET
    Inscrit en
    Novembre 2010
    Messages
    2 066
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Novembre 2010
    Messages : 2 066
    Points : 4 233
    Points
    4 233
    Par défaut
    pas mal ta solution Nathanael qui s'affranchit du type de List, justement je me demandais c'était quoi ce Dump?
    Je pense que je peux passer à résolu.

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

Discussions similaires

  1. Binding HS avec une requête LINQ retournant plusieurs tables
    Par abbepierre94 dans le forum Silverlight
    Réponses: 4
    Dernier message: 01/02/2011, 11h19
  2. Réponses: 14
    Dernier message: 22/12/2008, 15h07
  3. [SQL] Affichage d'une valeur depuis une requête
    Par kitty2006 dans le forum PHP & Base de données
    Réponses: 7
    Dernier message: 19/09/2006, 16h38
  4. Réponses: 2
    Dernier message: 31/10/2005, 17h25
  5. Retourner un tableau depuis une fonction
    Par obalais dans le forum C++
    Réponses: 2
    Dernier message: 20/10/2005, 16h49

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