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 :

[IDictionnary] Transformation liste Key/Value en Exression de filtrage Where


Sujet :

C#

  1. #1
    Membre actif
    Homme Profil pro
    Freelance
    Inscrit en
    Décembre 2003
    Messages
    423
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France

    Informations professionnelles :
    Activité : Freelance

    Informations forums :
    Inscription : Décembre 2003
    Messages : 423
    Points : 259
    Points
    259
    Par défaut [IDictionnary] Transformation liste Key/Value en Exression de filtrage Where
    Bonjour,

    Je souhaite, à partir d'un Dictionnaire, générer une Expression "LinQ compliant" pour une utilisation avec AMS.
    Imaginons le bout de code suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    Dictionnary<string, string> filters = new Dictionnary<string, string>{
        {"firstname", "Jean"},
        {"lastname", "Paul"}
    }
    Comment parcourir/transformer cet objet en quelque chose d'exploitable par un Where "Linq" dont l'idée est de filtrer automatiquement ma row selon les champs dont le nom de colonne est la key du dictionnary et la value la value du Dictionnary.

    En gros, partant de l'objet ci-dessus, je souhaiterais que le filtrage effectué soit comme si j'avais moi-même codé :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    myTable.Where(row => row.firstname == "Jean" && row.lastname == "Paul")....
    Sauf que je souhaiterais que ceci soit "dynamique" puisque je ne connais à priori pas ni la taille ni les "key" utilisées. Dans l'immédiat, la seule manière que je vois, mais qui ne me satisfait que moyennement, serait de se baser soit sur un Parser soit sur un gros Switch... mais peut-on faire mieux ?
    En gros existerait-il un moyen de faire quelque chose comme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    foreach (KeyValuePair kvp in filters) {
        myTable.Where(row => row[kvp.Key] == kvp.Value)
    }
    Pour information, l'objet myTable est de type IMobileServiceTable<T> : http://msdn.microsoft.com/en-us/library/jj554297.aspx

    Par avance, merci
    "La théorie, c’est quand on sait tout et que rien ne fonctionne. La pratique, c’est quand tout fonctionne et que personne ne sait pourquoi. Ici, nous avons réuni théorie et pratique : rien ne fonctionne ... et personne ne sait pourquoi !" et malheureusement c'est souvent le cas en Développement...

  2. #2
    Membre expert
    Avatar de Pragmateek
    Homme Profil pro
    Formateur expert .Net/C#
    Inscrit en
    Mars 2006
    Messages
    2 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Formateur expert .Net/C#
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 635
    Points : 3 958
    Points
    3 958
    Par défaut
    C'est un cas d'utilisation pour de la réflexion.

    Regarde du côté de GetType() pour obtenir un objet Type décrivant le type effectif.
    Puis récupère les champs via GetField() puis GetValue() pour en extraire les valeurs.
    Ne restera plus qu'à les comparer aux valeurs désirées.

    C'est l'idée, après on a souvent des surprises avec la réflexion.
    Formateur expert .Net/C#/WPF/EF Certifié MCP disponible sur Paris, province et pays limitrophes (enseignement en français uniquement).
    Mon blog : pragmateek.com

  3. #3
    Membre actif
    Homme Profil pro
    Freelance
    Inscrit en
    Décembre 2003
    Messages
    423
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France

    Informations professionnelles :
    Activité : Freelance

    Informations forums :
    Inscription : Décembre 2003
    Messages : 423
    Points : 259
    Points
    259
    Par défaut
    Merci Pragmateek.

    En fait, plus j'y pense et plus je me dis que ce n'est pas une bonne façon de faire, et que je pense trop "comme un autre langage de développement".

    En fait, je pense que créer directement l'expression plutôt qu'un Dictionnaire sera plus simple...

    Je vais voir si ça peut fonctionner.

    Merci,
    "La théorie, c’est quand on sait tout et que rien ne fonctionne. La pratique, c’est quand tout fonctionne et que personne ne sait pourquoi. Ici, nous avons réuni théorie et pratique : rien ne fonctionne ... et personne ne sait pourquoi !" et malheureusement c'est souvent le cas en Développement...

  4. #4
    Membre émérite Avatar de meziantou
    Homme Profil pro
    Ingénieur R&D
    Inscrit en
    Avril 2010
    Messages
    1 223
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : Canada

    Informations professionnelles :
    Activité : Ingénieur R&D
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2010
    Messages : 1 223
    Points : 2 439
    Points
    2 439
    Par défaut
    La méthode Where prend en paramètre une expression. Tu devrais donc pouvoir la créer à la main:

    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
    static void Main()
    {
        Dictionary<string, object> args = new Dictionary<string, object>();
        args.Add("Email", "john.doe@sample.com");
     
        Expression<Func<User, bool>> expression = MakeExpression<User>(args);
        var query = myTable.Where(expression);
        // ...
    }
     
    public static Expression<Func<T, bool>> MakeExpression<T>(Dictionary<string, object> args)
    {
        Expression e = Expression.Constant(true);
        ParameterExpression parameter = Expression.Parameter(typeof(T));
        foreach (var o in args)
        {
            MemberExpression leftExpression = Expression.Property(parameter, o.Key);
            ConstantExpression rightExpression = Expression.Constant(o.Value);
            BinaryExpression equalExpression = Expression.Equal(leftExpression, rightExpression);
     
            e = Expression.AndAlso(e, equalExpression);
        }
     
        return Expression.Lambda<Func<T, bool>>(e, parameter);
    }

  5. #5
    Membre actif
    Homme Profil pro
    Freelance
    Inscrit en
    Décembre 2003
    Messages
    423
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France

    Informations professionnelles :
    Activité : Freelance

    Informations forums :
    Inscription : Décembre 2003
    Messages : 423
    Points : 259
    Points
    259
    Par défaut
    Bonsoir meziantou,

    Wahou, bha voilà, c'est exactement ce que je cherchais, sauf que je ne savais pas comment ça se faisait.

    Je teste demain et je reviens fermer le sujet.

    Merci !!
    "La théorie, c’est quand on sait tout et que rien ne fonctionne. La pratique, c’est quand tout fonctionne et que personne ne sait pourquoi. Ici, nous avons réuni théorie et pratique : rien ne fonctionne ... et personne ne sait pourquoi !" et malheureusement c'est souvent le cas en Développement...

  6. #6
    Membre actif
    Homme Profil pro
    Freelance
    Inscrit en
    Décembre 2003
    Messages
    423
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France

    Informations professionnelles :
    Activité : Freelance

    Informations forums :
    Inscription : Décembre 2003
    Messages : 423
    Points : 259
    Points
    259
    Par défaut
    Bonjour,

    Pardon pour cette réponse tardive, mais la construction dynamique d'une Expression proposée par meziantou fonctionne parfaitement (utilisée dans un filter finalement via un appel à compile() du retour de l'expression).

    Merci encore !
    "La théorie, c’est quand on sait tout et que rien ne fonctionne. La pratique, c’est quand tout fonctionne et que personne ne sait pourquoi. Ici, nous avons réuni théorie et pratique : rien ne fonctionne ... et personne ne sait pourquoi !" et malheureusement c'est souvent le cas en Développement...

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

Discussions similaires

  1. Réponses: 2
    Dernier message: 23/01/2008, 16h26
  2. [1.1] Conteneur <key, value> réversible
    Par Monstros Velu dans le forum C#
    Réponses: 4
    Dernier message: 19/02/2007, 15h58
  3. Réponses: 1
    Dernier message: 03/01/2007, 21h34
  4. [Tableaux] Obtenir liste keys
    Par Fabouney dans le forum Langage
    Réponses: 2
    Dernier message: 27/09/2006, 12h28
  5. Réponses: 9
    Dernier message: 30/03/2006, 20h16

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