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 :

[LINQ] Réaliser des filtres successifs sur un wrapper d'objets


Sujet :

VB.NET

  1. #1
    Expert confirmé
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Points : 4 239
    Points
    4 239
    Par défaut [LINQ] Réaliser des filtres successifs sur un wrapper d'objets
    Hello,

    Je rentre directement dans le vif du sujet avec un bout de 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
     
        Private Sub btnFilter_Click(sender As Object, e As EventArgs)
            Dim data = (From d In Promo.DTO.DetailsDemo
                        Select Id = d.Id, Department = d.CodeDemo.Department, CodeDemo = d.CodeDemo, Percentage = d.Percentage, Description = d.Description, Note = d.Note, ListType = d.ListType
                        From d In Promo.DTO.DetailsDepartment
                        Select Id = d.Id, Department = d.Department, CodeDemo = New PROMO_DTO.CodeDemo(0, "0000", "", "", Nothing, Nothing, Nothing, Nothing, Nothing, False), Percentage = d.Percentage, Description = d.Description, Note = d.Note, ListType = d.ListType).ToList
     
     
            If ckbDepartment.Checked Then
                data = (From d In data
                        Where d.Department.Id = CShort(cbDepartment.SelectedValue)
                        Select d).ToList
            End If
     
            If ckbConcession.Checked Then
                data = (From d In data
                        Where d.CodeDemo.Id = CInt(cbConcession.SelectedValue)
                        Select d).ToList
            End If
     
            If ckbPercent.Checked Then
                data = (From d In data
                        Where d.Percentage = nudPercent.Value
                        Select d).ToList
            End If
     
            dgvDemo.DataSource = data
     
        End Sub
    J'ai donc data qui est wrapper autour d'objets similaire mais différents (l'un possède une propriété CodeDemo et l'autre non). Or j'ai besoin de donner la possibilité à l'utilisateur de filtrer le contenu de ce wrapper suivant 3 critères qui peuvent se combiner.

    J'ai donc utiliser des checkboxes pour activer ou non le critère de filtrage et si c'est coché, je fais le filtre.

    A priori, je trouve ça plutôt propre mais j'aurais voulu avoir votre avis.

    Aussi, je cherche une manière plus élégante pour boucher le trou que devrait occuper la propriété CodeDemo dans la 2e selection de mon wrapper...
    Actuellement, j'ai donc ceci (je remets le code du dessus) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
            Dim data = (From d In Promo.DTO.DetailsDemo
                         Select Id = d.Id, Department = d.CodeDemo.Department, CodeDemo =  d.CodeDemo, Percentage = d.Percentage, Description = d.Description, Note  = d.Note, ListType = d.ListType
                        From d In Promo.DTO.DetailsDepartment
                         Select Id = d.Id, Department = d.Department, CodeDemo = New  PROMO_DTO.CodeDemo(0, "0000", "", "", Nothing, Nothing, Nothing,  Nothing, Nothing, False), Percentage = d.Percentage, Description =  d.Description, Note = d.Note, ListType = d.ListType).ToList
    C'est donc le New PROMO_DTO.CodeDemo(0, "0000", "", "", Nothing, Nothing, Nothing, Nothing, Nothing, False) qui m'ennuie. Je peux mettre nothing et le wrapper est valide mais la propriété du type anonyme est alors de type Object et non pas de type CodeDemo et du coup, pas moyen de faire le filtre (à moins que je puisse faire un cast au moment du filtrage... je viens d'y penser).
    J'aimerais assez ne pas devoir créer un dummy CodeDemo dans ce second select.

    Une idée ?? (j'ai tenté la recherche sur le net mais vu que j'ignore les mots clefs à utiliser, je n'ai pas trouvé mon bonheur)
    Kropernic

  2. #2
    Membre chevronné
    Avatar de Sehnsucht
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Octobre 2008
    Messages
    847
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Lot et Garonne (Aquitaine)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Octobre 2008
    Messages : 847
    Points : 2 209
    Points
    2 209
    Par défaut
    Perso ce qui me gêne c'est que tu fais à chaque fois un ToList sur tes requetes donc tu construis potentiellement 4 listes (et selon la volumétrie que tu as ça peut être lourd).
    Pourquoi ne pas faire le ToList qu'à la fin et donc créer une seule requête au fur et à mesure (et l'appel au ToList lancera l'exécution du tout juste à la fin).

    Après pour l'histoire du CodeDemo à Nothing qui devient typé Object dans le type anonyme ; tu n'aurais pas le problème s'il ne s'agissait pas d'un type anonyme mais sinon il te suffit de typer explicitement le Nothing que tu passes à ton type anonyme
    Select ... CodeDemo = DirectCast(Nothing, CodeDemo)Ce qui me préoccupe le plus c'est que je ne suis pas certain que ton data initial te donne ce que tu attends ; le fait d'enchainer tes 2 From / Select ne va pas "concaténer" les résultats des 2 sous-requetes ; un exemple rapide pour illustrer :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Dim query = From c1 In "hello" Select c1
                From c2 In "world" Select c2
    Si on itérait sur les éléments de query on obtiendrait pas ``helloworld`` mais plutôt ``worldworldworldworldworld`` ; pas sûr du coup que ce soit ce que tu souhaites à mon avis tu souhaites plutôt ceci (en reprenant mon exemple) :
    Dim query = (From c In "hello" Select c).Concat(From c In "world" Select c)
    Nous sommes tous plus ou moins geek : ce qui est inutile nous est parfaitement indispensable ( © Celira )
    À quelle heure dormez-vous ?
    Censément, quelqu'un de sensé est censé s'exprimer sensément.

  3. #3
    Expert confirmé
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Points : 4 239
    Points
    4 239
    Par défaut
    Hello Sehnsucht,

    Tu as probablement raison pour ma query initiale. Je n'ai pas encore de données pour tester et vu que je ne fais jamais de requêtes "complexes", j'ai tapé ça au pifomètre^^.
    Je note donc ta suggestion .

    Pour les .ToList à répétition, je veux bien m'en passer mais comment construis-tu une requête au fur et à mesure ??
    Kropernic

  4. #4
    Membre chevronné
    Avatar de Sehnsucht
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Octobre 2008
    Messages
    847
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Lot et Garonne (Aquitaine)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Octobre 2008
    Messages : 847
    Points : 2 209
    Points
    2 209
    Par défaut
    en enlevant les ToList et en profitant de l'exécution différée
    Nous sommes tous plus ou moins geek : ce qui est inutile nous est parfaitement indispensable ( © Celira )
    À quelle heure dormez-vous ?
    Censément, quelqu'un de sensé est censé s'exprimer sensément.

  5. #5
    Expert confirmé
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Points : 4 239
    Points
    4 239
    Par défaut
    Fichtre, ça marche !

    J'avais pourtant tenté un truc du genre et VS me râlait dessus (un truc du genre impossible de convertir le type anonyme en un autre truc dont je n'ai pas retenu le nom).

    Forcément, j'avais du faire quelque chose de travers .

    Bref, ça me semble nickel maintenant.

    La query ne s'exécute qu'une seule fois et je n'ai pas de dummy codedemo dans mon wrapper. Merci !

    Que demander de plus ? ... Ah si ! Un p'tit café ! *s'en va à la machine*
    Kropernic

  6. #6
    Expert confirmé
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Points : 4 239
    Points
    4 239
    Par défaut
    Hello,

    Je reviens sur le sujet car j'aborde l'autre partie du projet et j'ai le même genre de souci que j'avais eu... Honnêtement, je ne pige pas...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
            Dim data = (From d In Promo.DTO.DetailsOwn
                        Select Id = d.Id, Department = d.Department, BrandCode = d.Brand.Code, BrandName = d.Brand.Description, Percentage = d.Percentage, PercentType = d.PercentType.Description, Description = d.Description, Note = d.Note, ListType = d.ListType).Concat(
                        From d In Promo.DTO.DetailsDepartment
                        Select id = d.Id, Department = d.Department, BrandCode = Nothing, BrandName = Nothing, Percentage = d.Percentage, PercentType = d.PercentType.Description, Description = d.Description, Note = d.Note, ListType = d.ListType)
    Voici le code et voici le message d'erreur :
    Error 1 'System.Collections.Generic.IEnumerable(Of <anonymous type>)' cannot be converted to 'System.Collections.Generic.IEnumerable(Of <anonymous type>)' because '<anonymous type> (line 219)' is not derived from '<anonymous type> (line 217)', as required for the 'Out' generic parameter 'T' in 'Interface IEnumerable(Of Out T)'.
    Je fais pourtant bien comme il a été dit plus haut non ?

    EDIT : Ce sont les =Nothing qu'il n'aime pas... J'avais mis cela car CAST(Nothing, Integer), il n'aimait pas non plus. Si je mets 0 directement (et "" pour le string), alors VS ne râle plus...

    EDIT 2 : Normal qu'il n'aime pas CAST(Nothing, Integer) vu que c'est CType ou DirectCast qu'il faut mettre (on va mettre ça sur le dos du lundi matin)
    Kropernic

  7. #7
    Membre confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2012
    Messages
    206
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2012
    Messages : 206
    Points : 455
    Points
    455
    Par défaut
    Oui c'est sur que mettre un Int à Nothing, il aime pas.
    Si tu veux vraiment le mettre à Nothing, il faut qu'il soit Nullable, ca marche pour n'importe qu'elle objet.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Dim iNullable As Integer?
    //or
    Dim iNullable As Nullable(Of Integer)
    Après il me semble que mettre un String à Nothing c'est censé passer.

  8. #8
    Membre chevronné
    Avatar de Sehnsucht
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Octobre 2008
    Messages
    847
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Lot et Garonne (Aquitaine)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Octobre 2008
    Messages : 847
    Points : 2 209
    Points
    2 209
    Par défaut
    Citation Envoyé par chaparo Voir le message
    Oui c'est sur que mettre un Int à Nothing
    Bien sûr que si il "aime" bien ; on peut très bien écrire Dim i As Integer = Nothing ça marchera sans soucis ; tout simplement parce que Nothing ce n'est pas null après il faut garder en tête que i vaudra bien 0 après car Nothing a plus valeur de default(type)

    Citation Envoyé par chaparo Voir le message
    (...) Nullable, ca marche pour n'importe qu'elle objet.
    Non ça ne marche que pour les type valeurs (structures) qui ne sont pas nullable ; logique les type références sont déjà nullables par défaut et un nullable de nullable ça serait redondant

    Pour le reste les edit de Kropernic et mon ancien post résument le tout ; assigner un champ d'un type à Nothing ça prendra le type Object par défaut, et donc incohérences entre les différents types anonymes ; il faut donc "typer" ce Nothing pour garder la cohérence des types anonymes entre eux.
    Nous sommes tous plus ou moins geek : ce qui est inutile nous est parfaitement indispensable ( © Celira )
    À quelle heure dormez-vous ?
    Censément, quelqu'un de sensé est censé s'exprimer sensément.

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

Discussions similaires

  1. Réaliser des filtres
    Par thomas.dusart dans le forum Access
    Réponses: 5
    Dernier message: 30/07/2010, 03h09
  2. Réponses: 4
    Dernier message: 03/07/2009, 19h06
  3. Filtres successifs sur formulaire
    Par rorobase dans le forum IHM
    Réponses: 5
    Dernier message: 16/09/2008, 16h11
  4. Filtres successifs sur un DAO.Recordset
    Par timoth dans le forum VBA Access
    Réponses: 5
    Dernier message: 07/03/2008, 13h13
  5. Réponses: 7
    Dernier message: 08/03/2004, 15h30

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