Précédent   Forum des professionnels en informatique > Dotnet > Accès aux données > Linq
Linq Forum d'entraide sur la manipulation de données avec Linq
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 20/01/2012, 09h19   #1
Membre confirmé
 
Homme Toto Browny
Développeur informatique
Inscription : mars 2008
Messages : 198
Détails du profil
Informations personnelles :
Nom : Homme Toto Browny
Âge : 31
Localisation : France, Haute Vienne (Limousin)

Informations professionnelles :
Activité : Développeur informatique
Secteur : Distribution

Informations forums :
Inscription : mars 2008
Messages : 198
Points : 206
Points : 206
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 :
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 :
 <%# 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 :
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
__________________
Créateur de bugs professionnel
Ma philosophie en 4 temps:
-Ce n'est qu'en essayant continuellement que l'on finit par réussir.
-Plus ça rate, plus on a de chances que ça marche.
-Ne jamais révéler tout son savoir
-...
BROWNY est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/01/2012, 10h34   #2
Responsable .NET
 
Avatar de tomlev
 
Homme Thomas Levesque
Développeur .NET
Inscription : février 2004
Messages : 16 728
Détails du profil
Informations personnelles :
Nom : Homme Thomas Levesque
Âge : 30
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 : 16 728
Points : 26 700
Points : 26 700
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...
__________________

Pas de questions techniques par MP ! Le forum est là pour ça...

Tutoriels : Les markup extensions en WPF - La sérialisation XML avec .NET (Aller plus loin) - Une visite guidée de WPF (traduction)
Projet : Dvp.NET, la librairie .NET open-source des membres de Developpez !

Envie de contribuer à la rubrique .NET ?
tomlev est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/01/2012, 14h08   #3
Membre confirmé
 
Homme Toto Browny
Développeur informatique
Inscription : mars 2008
Messages : 198
Détails du profil
Informations personnelles :
Nom : Homme Toto Browny
Âge : 31
Localisation : France, Haute Vienne (Limousin)

Informations professionnelles :
Activité : Développeur informatique
Secteur : Distribution

Informations forums :
Inscription : mars 2008
Messages : 198
Points : 206
Points : 206
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 :
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 :
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
__________________
Créateur de bugs professionnel
Ma philosophie en 4 temps:
-Ce n'est qu'en essayant continuellement que l'on finit par réussir.
-Plus ça rate, plus on a de chances que ça marche.
-Ne jamais révéler tout son savoir
-...
BROWNY est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/01/2012, 16h33   #4
Responsable .NET
 
Avatar de tomlev
 
Homme Thomas Levesque
Développeur .NET
Inscription : février 2004
Messages : 16 728
Détails du profil
Informations personnelles :
Nom : Homme Thomas Levesque
Âge : 30
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 : 16 728
Points : 26 700
Points : 26 700
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
__________________

Pas de questions techniques par MP ! Le forum est là pour ça...

Tutoriels : Les markup extensions en WPF - La sérialisation XML avec .NET (Aller plus loin) - Une visite guidée de WPF (traduction)
Projet : Dvp.NET, la librairie .NET open-source des membres de Developpez !

Envie de contribuer à la rubrique .NET ?
tomlev est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 24/01/2012, 14h56   #5
Membre confirmé
 
Homme Toto Browny
Développeur informatique
Inscription : mars 2008
Messages : 198
Détails du profil
Informations personnelles :
Nom : Homme Toto Browny
Âge : 31
Localisation : France, Haute Vienne (Limousin)

Informations professionnelles :
Activité : Développeur informatique
Secteur : Distribution

Informations forums :
Inscription : mars 2008
Messages : 198
Points : 206
Points : 206
Je suppose que tu as raison ...
Faudra que j'essaie lors de la prochaine publication

Merci
__________________
Créateur de bugs professionnel
Ma philosophie en 4 temps:
-Ce n'est qu'en essayant continuellement que l'on finit par réussir.
-Plus ça rate, plus on a de chances que ça marche.
-Ne jamais révéler tout son savoir
-...
BROWNY est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 02h50.


 
 
 
 
Partenaires

Hébergement Web