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 :

Join multiple linq et dataset


Sujet :

Linq

  1. #1
    Membre expérimenté
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2008
    Messages
    1 051
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Hautes Pyrénées (Midi Pyrénées)

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

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 051
    Points : 1 638
    Points
    1 638
    Par défaut Join multiple linq et dataset
    Bonjour,

    Je rencontre un gros soucis, sur lequel je bloque depuis quelques heures ..

    J'ai un dataset qui comporte 4 tables. J'ai une table principale qui comporte des éléments (dont une clé primaire) et 3 tables annexes. Les 3 tables sont indépendantes mais comportent des caractéristiques par rapport à la clé primaire de la table principale.

    J'aimerais faire une requête qui récupére tous les enregistrements où
    table1.cléprimaire = table2.ID && ( || ?)
    table1.cléprimaire = table3.ID && ( || ?)
    table1.cléprimaire = table4.ID && ( || ?)

    J'ai tenté cette requête :
    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
    var requete = from A in table1.AsEnumerable()
                              //from C in table3.AsEnumerable()
                              join B in table2.AsEnumerable()
                                 on A["TPLNR"] equals B["TPLNR"]
                              join C in table3.AsEnumerable()
                                 on A["TPLNR"] equals C["TPLNR"]
                              //where A["TPLNR"] == B["TPLNR"] || A["TPLNR"] == C["TPLNR"]
                              join D in table4.AsEnumerable()
                                 on A["TPLNR"] equals D["TPLNR"]
                              select new
                              {
                                  BEBER = A.Field<string>("BEBER"),
                                  EVENT = A.Field<string>("EVENT"),
                                  UNIT_FROM = B.Field<string>("UNIT_FROM"),
                                  VALUE_FROM = C.Field<string>("VALUE_FROM")
                              };
    Cependant cela me retourne 0 enregistrement. Par contre si je laisse seulement une seule jointure entre A et B, ca fonctionne .. c'est la jointure multiple qui fonctionne pas

    En sql je sais faire, mais j'ai du mal à traduire :/ J'ai regardé beaucoup de tuto, mais souvent pas de join multiple, ou alors leur solution ne fonctionne pas chez moi, je dois louper une étape ..

    Merci !
    Règle N° 1 : Si tout va bien, ne touchez à rien.

  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 : 42
    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
    Points : 39 749
    Points
    39 749
    Par défaut
    Est-ce que la clé existe dans toutes les tables ? S'il y a ne serait-ce qu'une table où elle n'existe pas, ça ne renvoie rien pour cette clé... Ou alors il faut faire une jointure externe

  3. #3
    Membre expérimenté
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2008
    Messages
    1 051
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Hautes Pyrénées (Midi Pyrénées)

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

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 051
    Points : 1 638
    Points
    1 638
    Par défaut
    Oui la clé existe dans toute les tables

    Cependant il se peut que pour un élément dans la table principale, une table ne retourne rien.

    Pour expliquer plus le contexte, j'ai un événement dans la table principale. Cet événement comporte diverses caractéristiques. Ces caractéristiques peuvent être de type numérique, caractère etc. En fait pour un type, on a une table annexe (connexion avec SAP donc pas le choix).

    Cependant je pense que SQL gère très bien le fait que s'il trouve rien dans une table, il passe au reste.

    Cependant c'est la première fois que j'utilise linq, et je remarque que les jointures multiples sont pas si simple qu'en SQL (enfin quand une fonctionnera ca ira mieux ).

    edit : il y a du nouveau. En fait ca fonctionne sauf que lui il fait le lien entre les jointures comme du ET. Sauf que moi il faudrait des jointures en OU. Tu vois ? Comment je peux faire ca sur du join ?

    Merci
    Règle N° 1 : Si tout va bien, ne touchez à rien.

  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 : 42
    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
    Points : 39 749
    Points
    39 749
    Par défaut
    Citation Envoyé par bob633 Voir le message
    Cependant il se peut que pour un élément dans la table principale, une table ne retourne rien.
    Oui, c'est ça que je voulais dire


    Citation Envoyé par bob633 Voir le message
    Cependant je pense que SQL gère très bien le fait que s'il trouve rien dans une table, il passe au reste.
    Sans doute parce qu'en SQL tu as fait une jointure externe

    Citation Envoyé par bob633 Voir le message
    edit : il y a du nouveau. En fait ca fonctionne sauf que lui il fait le lien entre les jointures comme du ET. Sauf que moi il faudrait des jointures en OU. Tu vois ? Comment je peux faire ca sur du join ?
    Comme je t'ai dit plus haut, il faut une jointure externe.

    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
                var requete = from A in table1.AsEnumerable()
                              join B in table2.AsEnumerable()
                                 on A["TPLNR"] equals B["TPLNR"] into tmp2
                                 from B in tmp2.DefaultIfEmpty()
                              join C in table3.AsEnumerable()
                                 on A["TPLNR"] equals C["TPLNR"] into tmp3
                                 from C in tmp3.DefaultIfEmpty()
                              join D in table4.AsEnumerable()
                                 on A["TPLNR"] equals D["TPLNR"] into tmp4
                                 from D in tmp3.DefaultIfEmpty()
                              select new
                              {
                                  BEBER = A.Field<string>("BEBER"),
                                  EVENT = A.Field<string>("EVENT"),
                                  UNIT_FROM = B =! null ? B.Field<string>("UNIT_FROM") : null,
                                  VALUE_FROM = C != null ? C.Field<string>("VALUE_FROM") : null
                              };

  5. #5
    Membre expérimenté
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2008
    Messages
    1 051
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Hautes Pyrénées (Midi Pyrénées)

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

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 051
    Points : 1 638
    Points
    1 638
    Par défaut
    Merci bien ca marche du feu !

    Par contre j'ai un peu de mal avec les expressions "jointures externes" et "jointures internes", et sur google ca me parle de jointure gauche interne, jointure droite externe .. je me perd un peu ? C'est pour comprendre tes lignes de jointures avec les clause defaultIfEmpty() ..


    edit : j'ai crié victoire trop vite .. J'ai fais mes tests voir ce que je récupérais exactement de ca. Le problème arrive lorsque pour un événement principal (table principale), il existe des caractéristiques dans au moins deux des trois autres tables, il me créé un seul enregistrement en prenant la valeur dans chacun des tables (en gros au lieu de faire un enregistrement pour la 1ere caractéristique, puis un deuxième pour la 2eme caractéristique, il prend les deux champs pour le même.

    Travaillant sur un projet pour faire communiquer deux applications, il est nécessaire d'avoir deux lignes distinctes :/ bien que ca peut faire redondance ...

    Je pense qu'il doit exister une condition qui permet de dire, si une des valeurs existe, alors l'autre est nulle :/ Mais j'ai peur d'alourdir énormément ma requête, et je sais pas si c'est possible directement dans le select (mes essais sont pas très concluant).

    Encore merci.
    Règle N° 1 : Si tout va bien, ne touchez à rien.

  6. #6
    Membre expérimenté
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2008
    Messages
    1 051
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Hautes Pyrénées (Midi Pyrénées)

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

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 051
    Points : 1 638
    Points
    1 638
    Par défaut
    Finalement j'ai compris le principe des DefaultIfEmpty, en fait on passe la main de table en table pour voir .. mais peut-on créer des enregistrements différents, même lorsqu'il trouve des correspondances entre plusieurs tables ?

    edit : En fait je me suis fait un jeu de test.
    Admettons 4 tables :

    A B C D

    v1 v1 v2 v1
    v2 v2 v2 v2

    Résultat :
    v1 v1
    v1 v1
    v2 v2 v2 v2
    v2 v2 v2 v2
    En gros il différencie pas qu'il y a qu'une valeur dans B puis 2 dans C etc Au final il réplique autant de fois que la table où il y en aura le plus. Sauf que le logiciel d'arrivé ne saura pas gérer ..

    Je pensais peut-être faire ensuite un traitement pour séparer les lignes mais bon là c'est complexe et "usine à gaz".
    Règle N° 1 : Si tout va bien, ne touchez à rien.

  7. #7
    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 : 42
    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
    Points : 39 749
    Points
    39 749
    Par défaut
    Citation Envoyé par bob633 Voir le message
    edit : j'ai crié victoire trop vite .. J'ai fais mes tests voir ce que je récupérais exactement de ca. Le problème arrive lorsque pour un événement principal (table principale), il existe des caractéristiques dans au moins deux des trois autres tables, il me créé un seul enregistrement en prenant la valeur dans chacun des tables (en gros au lieu de faire un enregistrement pour la 1ere caractéristique, puis un deuxième pour la 2eme caractéristique, il prend les deux champs pour le même.
    Ah ok... j'avais pas bien compris ce que tu voulais alors. Tu peux montrer à quoi ressemblait ta requête SQL d'origine ? ce sera plus clair

  8. #8
    Membre expérimenté
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2008
    Messages
    1 051
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Hautes Pyrénées (Midi Pyrénées)

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

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 051
    Points : 1 638
    Points
    1 638
    Par défaut
    Je suis directement passé par Linq en fait.

    J'ai 4 tables : A, B, C et D

    A se trouve au centre. B, C et D ont dont une clé étrangère de A.

    En fait la requête doit d'abord chercher les valeurs entre A et B, puis entre A et C, puis entre A et D où B, C et D sont complétement indépendants en fait.

    Je pense qu'en SQL normal ca devrait ressembler à :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    select A.beber, B.unit_from, C.unit_char from A, B, C
    where A.id == B.idCE || A.id == C.idCE ;
    J'ai pas testé donc je sais pas si ça fonctionnerait le fait de faire des "OU" entre les id mais l'idée est là, on pioche dans les autres tables.

    Je sais pas si j'arrive à expliquer :/
    Règle N° 1 : Si tout va bien, ne touchez à rien.

  9. #9
    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 : 42
    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
    Points : 39 749
    Points
    39 749
    Par défaut
    En fait, l'instruction join de Linq correspond à une équijointure. Le code SQL que tu montres réalise une jointure cartésienne et filtre les résultats ensuite. Pour faire l'équivalent avec Linq, il faut faire quelque chose comme ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    var requete = from A in table1.AsEnumerable()
                  from B in table2.AsEnumerable()
                  from C in table3.AsEnumerable()
                  where A.Field<int>("TPLNR") == B.Field<int>("TPLNR") || A.Field<int>("TPLNR") == C.Field<int>("TPLNR")
                  select new
                  {
                      BEBER = A.Field<string>("BEBER"),
                      EVENT = A.Field<string>("EVENT"),
                      UNIT_FROM = B =! null ? B.Field<string>("UNIT_FROM") : null,
                      VALUE_FROM = C != null ? C.Field<string>("VALUE_FROM") : null
                  };
    (note l'utilisation de la méthode Field à la place de l'indexeur ; si tu utilises l'indexeur, ça renvoie un object, et l'opérateur == fera donc une comparaison de référence, ce qui n'est pas le comportement souhaité)

  10. #10
    Membre expérimenté
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2008
    Messages
    1 051
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Hautes Pyrénées (Midi Pyrénées)

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

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 051
    Points : 1 638
    Points
    1 638
    Par défaut
    Parfait, c'est ce que je cherchais =)

    Merci beaucoup
    Règle N° 1 : Si tout va bien, ne touchez à rien.

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

Discussions similaires

  1. [Débutant] Cross Join avec Linq to Dataset
    Par Drakonis dans le forum VB.NET
    Réponses: 1
    Dernier message: 06/07/2012, 10h07
  2. Linq to Dataset Join
    Par Pelote2012 dans le forum Linq
    Réponses: 4
    Dernier message: 24/01/2012, 14h56
  3. Outer Join multiples sous Access 2003
    Par ptite_bebete dans le forum Requêtes et SQL.
    Réponses: 3
    Dernier message: 03/06/2008, 22h49
  4. Outer Join multiples
    Par ptite_bebete dans le forum Requêtes et SQL.
    Réponses: 1
    Dernier message: 30/05/2008, 15h20
  5. left join multiple sur grosses tables
    Par hn2k5 dans le forum Requêtes
    Réponses: 6
    Dernier message: 30/11/2005, 16h10

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