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

Linq Discussion :

Linq to Dataset Join


Sujet :

Linq

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éprouvé
    Avatar de Pelote2012
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2008
    Messages
    925
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Haute Vienne (Limousin)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2008
    Messages : 925
    Billets dans le blog
    2
    Par défaut Linq to Dataset Join
    Juste pour la postérité ...
    Comme j'ai galéré pour le mettre au point, je partage un bout de code qui je l'espère aidera tous les newbies du Linq comme moi.

    La problématique:
    Un repeater à remplir avec une liste de commande (source un dataview).
    Sur ce repeater, j'ai un filtre multiple critère. Or un de ces critères est le constructeur. Mais les constructeurs (les articles de la commandes) sont dans un 2eme dataview.

    Solutions 1:
    Je refais une requête SQL avec toutes la lourdeur de faire des appels entre mon site et la BDD

    Solution 2:
    Je fais un join par Linq de mes 2 dataview, donc un seul appel à la BDD
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
                Dim Lines = dtvLigne.Table.AsEnumerable()
                Dim Entetes = dtvCommandes.Table.AsEnumerable()
     
    (From ent In Entetes Join Lin In Lines On ent("cIdDistri") Equals Lin("cIdDistri") And ent("cIdSociete") Equals Lin("cIdSociete") And ent("cRefCdeDistri") Equals Lin("cRefCdeDistri") _
                        Select New DAL.BacklogEntete With {.cIdDistri = ent("cIdDistri"), .cIdSociete = ent("cIdSociete"), .cRefCdeDistri = ent("cRefCdeDistri"), .dDateCommande = ent("dDateCommande"), _
                                                               .cDemandeur = ent("cDemandeur"), .cModeReglement = ent("cModeReglement"), .AdEmetteur = ent("AdEmetteur"), .AdLivraison = ent("AdLivraison"), _
                                                               .AdFacturation = ent("AdFacturation"), .cStatutCde2 = ent("cStatutCde2"), .cStatutFac = ent("cStatutFac"), _
                                                               .nTotalHT = ent("nTotalHT"), .nTotalTTC = ent("nTotalTTC"), .cComURL = ent("cComURL")}).ToList
    Ps: DAL.BacklogEntete est une classe qui me permet de remplir mon repeater directement dans la page *.aspx
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     <%# String.Format("{0:dd/MM/yyyy}", Eval("dDateCommande"))%>
    Pour ceux comme moi, qui sur ce vieux projets, utilise un générateur de code pour les accès à la BDD, on peux rajouter des champs à la classe générée automatiquement en créant dans un autre fichier (sinon il sera écrasé par la prochaine génération de code automatique)
    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
     
    Partial Class BacklogEntete
     Private _cDemandeur As String
        Public Property cDemandeur As String
            Get
                Return _cDemandeur
            End Get
            Set(value As String)
                _cDemandeur = value
            End Set
        End Property
     
    ...
     
    End Class

  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 : 44
    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
    Par défaut
    Citation Envoyé par BROWNY Voir le message
    Je fais un join par Linq de mes 2 dataview, donc un seul appel à la BDD
    Dans ton code tu fais un join entre les DataTable, pas les DataView (dtvLigne.Table, dtvCommandes.Table). Et ça ne fait aucun appel à la BDD : les données sont en mémoire, les appels à la BDD ont déjà été faits avant pour remplir les DataTable...

  3. #3
    Membre éprouvé
    Avatar de Pelote2012
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2008
    Messages
    925
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Haute Vienne (Limousin)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2008
    Messages : 925
    Billets dans le blog
    2
    Par défaut
    Oui je suis d'accord, c'est ce que j'essayé de dire ...
    L'appel à la BDD se fait que pour la solution 1 (celle que j'aurais fait sans l'existence de Linq)

    Je précise aussi que, j'ai fait une correction au code car en faisant dataview.table , on perd les rowfilter et le sort
    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
     
    Private Function GereData() As DataView
     
            Dim strFiltreLine As String = String.Empty
     
            If lstConstructeurs.SelectedValue <> "" AndAlso lstConstructeurs.SelectedValue <> "-1" Then strFiltreLine = "cConstructeur='" & lstConstructeurs.SelectedValue & "'"
     
            If (txtArticles.Text.Trim <> "" And txtArticles.Text.Length >= 3) Then
     
            End If
     
            Dim dtv As DataView = Nothing
            If strFiltreLine = String.Empty Then
                dtv = dtvCommandes
            Else
                Dim Entetes = dtvCommandes.Table.AsEnumerable()
                Dim Lines = dsBacklog.Tables("Lignes").AsDataView
                Lines.RowFilter = strFiltreLine
     
                dtv = (From ent In Entetes Join Lin In Lines On ent("cIdDistri") Equals Lin("cIdDistri") And ent("cIdSociete") Equals Lin("cIdSociete") And ent("cRefCdeDistri") Equals Lin("cRefCdeDistri") Select ent Distinct).CopyToDataTable.DefaultView
            End If
     
            dtv.RowFilter = GestFiltre()
            dtv.Sort = GestTri()
            Return dtv
        End Function
    Cette solution est plus agréable car elle ne casse pas toute la structure de mon projet et je n'ai plus besoin d'injecter le résultat dans une classe.

    Par contre, je ne comprends pas pourquoi, je ne peux pas faire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    dtvCommandes.Table.AsDataView
    Dim Lines = dsBacklog.Tables("Lignes").AsDataView
    Lines.RowFilter = strFiltreLine
    dtv = (From ent In Entetes Join Lin In Lines On ent("cIdDistri") Equals Lin("cIdDistri") And ent("cIdSociete") Equals Lin("cIdSociete") And ent("cRefCdeDistri") Equals Lin("cRefCdeDistri") Select ent Distinct)
    Il me sort une insulte du genre pas de cast entre dataview et un truc qui doit être une structure issu du mode anonyme (DI_7....)
    J'ai vraiment du mal avec les type de retour de Linq

  4. #4
    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 : 44
    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
    Par défaut
    Le type de retour de ta requête est IEnumerable<DataRow>, tu ne peux donc pas l'affecter à un DataView... par contre avec un AsDataView derrière, ça devrait le faire

  5. #5
    Membre éprouvé
    Avatar de Pelote2012
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2008
    Messages
    925
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Haute Vienne (Limousin)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2008
    Messages : 925
    Billets dans le blog
    2
    Par défaut
    Je suppose que tu as raison ...
    Faudra que j'essaie lors de la prochaine publication

    Merci

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

Discussions similaires

  1. linq to typed dataset : join + group + sum
    Par laumon dans le forum Linq
    Réponses: 4
    Dernier message: 25/04/2013, 09h29
  2. [Débutant] Cross Join avec Linq to Dataset
    Par Drakonis dans le forum VB.NET
    Réponses: 1
    Dernier message: 06/07/2012, 10h07
  3. Join multiple linq et dataset
    Par bob633 dans le forum Linq
    Réponses: 9
    Dernier message: 18/10/2011, 16h39
  4. Réponses: 1
    Dernier message: 10/12/2009, 23h02
  5. Linq et dataset fortement typé
    Par stdebordeau dans le forum Windows Forms
    Réponses: 1
    Dernier message: 17/05/2009, 20h45

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