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 :

Order By Lambda sur une arborescence d'objet


Sujet :

C#

  1. #1
    Nouveau Candidat au Club
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Novembre 2012
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

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

    Informations forums :
    Inscription : Novembre 2012
    Messages : 4
    Points : 1
    Points
    1
    Par défaut Order By Lambda sur une arborescence d'objet
    Bonjour,

    J'ai une problématique d'expressions lambda. L'idée est de trier une liste en fonction de propriétés contenues dans une arborescence de chaque objet (profondeur de 1 à 5 sur le projet réel en fonction de la demande).
    Pour ce faire, on crée un expression lambda en dehors de Linq via des ExpressionMember (code simplifié).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    var param = Expression.Parameter(typeof(MaClasse));
                SortDirection sortDirection = SortDirection.Descending;
                MemberExpression keySelectExpr = Expression.Property(Expression.Property(param, "MaSousClasse"), "MonNom") ;
                // On utiliser la classe Sorter définie dans l'assembly courante
                IList<MaClasse> orderedList = new SorterClass<MaClasse>().Sort(maListe, param, keySelectExpr, sortDirection);
    avec la classe "MaClasse" super complexe:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    class MaClasse
        {
            public String MonNom { get; set; }
            public MaClasse MaSousClasse { get; set; }
        }
    L'évaluation fonctionne bien si tous les chemins existent (toutes les instances de MaClasse de premier niveau contiennent une référence) mais l'évaluation plante s'il manque au moins une des sous références. Ainsi avec la liste suivante:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    IList<MaClasse> maListe = new List<MaClasse> { 
                    new MaClasse{MonNom = "AAAA", MaSousClasse = new MaClasse{MonNom = "BBBB.AAAA"}},
                    new MaClasse{MonNom = "Test", MaSousClasse = null}};
    L'évaluation "MaSousClasse.MonNom" ne peut s'exécuter car l'une des références de MaSousClasse est vide.
    Une exception de type NullReferenceException est levée par le Convert.

    Est-ce qu'il y a un moyen pour intervenir lors de l'évaluation pour chaque instance ?
    Ou est-ce qu'il y a un moyen de lui fournir une valeur par défaut lorsqu'une référence est nulle ?
    Ou un autre moyen ?

    Yannick

  2. #2
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    332
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Juin 2002
    Messages : 332
    Points : 502
    Points
    502
    Par défaut
    Salut,

    Personnellement, je n'ai jamais vu en 12 ans le besoin de créer une hiérarchie aussi 'tightly coupled' que ça.

    Pourquoi as-tu besoin d'avoir cette hiérarchie? Est-ce qu'elle ne pourrait pas être implicite à un plus grand ensemble?

    Si c'est pour faire du 'traversal', peut-être qu'un graph serait plus approprié...

  3. #3
    Nouveau Candidat au Club
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Novembre 2012
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

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

    Informations forums :
    Inscription : Novembre 2012
    Messages : 4
    Points : 1
    Points
    1
    Par défaut
    Salut Babyneedle,

    Je n'ai malheureusement pas possibilité de modifier cette architecture qui a été mise en place il y'a quelques temps.

    L'exemple que j'ai publié sur mon premier post est un exemple simplifié de mon problème. En situation réelle la méthode de tri est générique et doit être capable de s'appliquer à tout type d'objet.

    Yannick

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    332
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Juin 2002
    Messages : 332
    Points : 502
    Points
    502
    Par défaut
    Pourrais-tu stp nous procurer un set de données plus nombreux (genre 5-6 instances) et surtout le résultat attendu après le order by?

  5. #5
    Membre émérite Avatar de Guulh
    Homme Profil pro
    Inscrit en
    Septembre 2007
    Messages
    2 160
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2007
    Messages : 2 160
    Points : 2 925
    Points
    2 925
    Par défaut
    Hello,
    ah, le besoin de trier selon une propriété / une suite de propriétés dans le genre object.Machin.Bidule

    J'ai eu un besoin similaire (pour info: pour des grilles WPF), et j'avais aussi eu recours aux expressions, pour générer des getters rapides. Malheureusement, je n'avais pas géré les suite de propriétés.
    Il faudrait voir, dans l'API des expression trees, quel est l'équivalent du if.
    De façon à pouvoir générer l'équivalent de cette méthode:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    if (machin != null && machin.Prop1 != null) && machin.Prop1.Prop2 !=null && ...)
      return machin.Prop1. ... . PropN;
    else
      return null; // ou une default value
    Ca devrait suffire.

  6. #6
    Membre averti
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2008
    Messages
    231
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Avril 2008
    Messages : 231
    Points : 359
    Points
    359
    Par défaut
    TU peux pas implémenter IComparable ?
    Je parle de tes classes qui sont imbriquées ...

    Je sais pas trop comment tu fais pour implémenter tes trucs à différent niveau mais les classes utilisées pourrait implémenter IComparable

    Tu aurais donc la méthode CompareTo c'est cette fameuse méthode qui est utilisé par la méthode List.Sort()

    Et dans ton CompareTo tu mets ton intelligence de comparaison (c'est ici que tu compares tes profondeurs)

    J'espère avoir été clair. Sinon je fais un exemple.

  7. #7
    Nouveau Candidat au Club
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Novembre 2012
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

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

    Informations forums :
    Inscription : Novembre 2012
    Messages : 4
    Points : 1
    Points
    1
    Par défaut
    Merci pour vos réponses.

    J'ai passé la journée a essayer de nombreuses parades à mon prolème.
    Sur le point de baisser les bras j'ai finalement trouvé une solution à la fois simple et efficace mais qui est loin d'être objet.

    Dans ce projet, une requête SQL codée en dure est passée à Entity Framework qui me retourne ma grappe d'objet. Pour rendre mon ORDER BY fonctionnel il m'a suffit d'effectuer le tri non pas sur les objets mais sur la requête elle même.

    A force de chercher dans une direction on en oublie de regarder les autres solutions, y compris celles qui sont les plus simple.

    Yannick

  8. #8
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    332
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Juin 2002
    Messages : 332
    Points : 502
    Points
    502
    Par défaut
    Tu parles comme si déléguer le triage à SQL était quelque chose de vilain. En fait, dans la très grande majorité des cas, il vaut mieux déléguer la discrimination et l'ordination à la base de données.

    J'ajouterais que pour tes prochaines questions, il serait bien de prendre du recul par rapport à un problème. Dans ce cas précis, tous les intervenants ont cru que tu étais limité à l'usage du code pour solutionner ton problème.

  9. #9
    Nouveau Candidat au Club
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Novembre 2012
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

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

    Informations forums :
    Inscription : Novembre 2012
    Messages : 4
    Points : 1
    Points
    1
    Par défaut
    J'avoue ne pas avoir pris le recul nécessaire sur ce problème.

    Comme la persistance de ce projet est assuré par Entity Framework je ne m’attendai pas à trouver une requête SQL en dure. Je n'ai d'ailleurs trouver cette solution que très tardivement, c'est pourquoi je n'en ai pas abordé cette piste ici.

    Je note ta remarque sur le fait de déléguer la discrimination et l'ordination à la base de données dans un coin de ma tête. Ça peut être utile pour un futur projet.

    Yannick

Discussions similaires

  1. Tri sur une liste d'objet
    Par Poussy-Puce dans le forum C#
    Réponses: 4
    Dernier message: 12/05/2008, 17h35
  2. Petit problème de requête sur une arborescence.
    Par grandpa006 dans le forum Requêtes
    Réponses: 1
    Dernier message: 06/03/2008, 09h29
  3. Réponses: 1
    Dernier message: 16/07/2007, 10h13
  4. Réponses: 4
    Dernier message: 08/05/2007, 09h57
  5. [Struts] <logic:iterate> sur une collection d objets c
    Par trax020 dans le forum Struts 1
    Réponses: 2
    Dernier message: 12/05/2005, 00h11

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