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 :

Jointures en linq


Sujet :

Linq

  1. #1
    r83
    r83 est déconnecté
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2003
    Messages
    271
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2003
    Messages : 271
    Points : 86
    Points
    86
    Par défaut Jointures en linq
    Bonjour,

    Ma classe Cour
    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
    public partial class COUR
        {
            [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
            public COUR()
            {
                this.SEMINAIREs = new HashSet<SEMINAIRE>();
            }
     
            public string CODECOURS { get; set; }
            public string LIBELLECOURS { get; set; }
            public decimal NBJOURS { get; set; }
     
            [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
            public virtual ICollection<SEMINAIRE> SEMINAIREs { get; set; }
        }
    ma classe Seminaire
    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
    public partial class SEMINAIRE
        {
            [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
            public SEMINAIRE()
            {
                this.INSCRITs = new HashSet<INSCRIT>();
            }
     
            public string CODESEMI { get; set; }
            public string CODECOURS { get; set; }
            public System.DateTime DATEDEBUTSEM { get; set; }
     
            public virtual COUR COUR { get; set; }
            [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
            public virtual ICollection<INSCRIT> INSCRITs { get; set; }
        }
    Ma question est simple....
    Requête 1 : j'aimerais ramener une collections d'objets de la classe Seminaire avec l'attribut COUR correctement renseigné
    Requête 2 : j'aimerais ramener une collection s'objets de la classe Cours avec la collection Seminaires renseignée.

    Pour la requête 1 j'arrive à avoir des résultats, mais je ne sais pas si c'est la bonne méthode
    Pour la requête 2, je n'ai rien trouvé de probant.

    Merci pour les retours,

    Cordialement

  2. #2
    Expert éminent sénior

    Avatar de François DORIN
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juillet 2016
    Messages
    2 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2016
    Messages : 2 761
    Points : 10 543
    Points
    10 543
    Billets dans le blog
    21
    Par défaut
    Bonsoir,

    Le plus simple pour commencer serait peut être de nous montrer ce que tu as actuellement comme code pour tes requêtes. On pourra ainsi te dire si la requête 1 est bonne, et te guider pour la requête 2.

  3. #3
    r83
    r83 est déconnecté
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2003
    Messages
    271
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2003
    Messages : 271
    Points : 86
    Points
    86
    Par défaut
    Merci pour le retour

    Requête 1 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     var requete = from s in oracleContexte.SEMINAIREs                              
                                  join COUR in oracleContexte.COURS on s.CODECOURS equals COUR.CODECOURS 
                                  select s;
                    var lesSeminaires = requete.ToList();
    Dans le cours microsoft MVA le formateur fait ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     var requete = from s in oracleContexte.SEMINAIREs                              
                                  from c COUR in oracleContexte.COURS 
                                  select s;
                    var lesSeminaires = requete.ToList();
    Mais la requête SQL générée fait un cross join, ce qui n'est pas bon du tout.

    Requête 2 :

    Elle est fausse :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     var reqCoursSemi = from c in oracleContexte.COURS
                                   join s in oracleContexte.SEMINAIREs on c.CODECOURS equals s.CODECOURS                           
                              select c;
                    var leCours = reqCoursSemi.ToList();
    Je chercje à remplir la collection Seminaires de la classe Cours

    Merci pour votre aide

  4. #4
    Expert éminent sénior

    Avatar de François DORIN
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juillet 2016
    Messages
    2 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2016
    Messages : 2 761
    Points : 10 543
    Points
    10 543
    Billets dans le blog
    21
    Par défaut
    Si tu as bien des clés étrangères entre tes deux tables, la solution simple serait d'utiliser Include, qui te permettra charger automatiquement les relations désirées.

    Et potentiellement cela allégerait de beaucoup l'écriture de tes requêtes !

    La première deviendrait :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    var lesSeminaires = oracleContexte.SEMINAIREs.Include("NOM_ASSOCIATION_COURS").ToList();
    Il te faut juste connaître le nom de l'association. Elle se trouve dans le fichier définissant ton contexte.

  5. #5
    r83
    r83 est déconnecté
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2003
    Messages
    271
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2003
    Messages : 271
    Points : 86
    Points
    86
    Par défaut
    Merci,

    Je n'ai pas de classes d'association dans la mesure où 1 cours = n séminaires mais 1 séminaire= 1 cours.

    Par contre je vais tester ce que vous me dites dans un autre contexte.

  6. #6
    r83
    r83 est déconnecté
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2003
    Messages
    271
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2003
    Messages : 271
    Points : 86
    Points
    86
    Par défaut
    Avec cette requête :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    var reqCoursSemi = from c in oracleContexte.COURS
                                       join s in oracleContexte.SEMINAIREs on c.CODECOURS equals s.CODECOURS into semis
                                       select c;
    J'obtiens ceci :

    Nom : linq_image.png
Affichages : 349
Taille : 11,4 Ko

    On voit bien que la collection Seminaires n'a pas été renseignée. C'est celle là que j'aimerais remplir dans ma requête.
    On voit aussi qu'il y a eu une erreur.

    Je suis en database first.

    Merci

  7. #7
    Membre éprouvé
    Homme Profil pro
    Architecte technique
    Inscrit en
    Septembre 2005
    Messages
    462
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 462
    Points : 1 056
    Points
    1 056
    Par défaut
    Citation Envoyé par r83 Voir le message
    Avec cette requête :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    var reqCoursSemi = from c in oracleContexte.COURS
                                       join s in oracleContexte.SEMINAIREs on c.CODECOURS equals s.CODECOURS into semis
                                       select c;
    Salut,

    Tu peux mettre le include :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    var reqCoursSemi = from c in oracleContexte.COURS.Include("SEMINAIRES")
                                       join s in oracleContexte.SEMINAIREs on c.CODECOURS equals s.CODECOURS into semis
                                       select c;

  8. #8
    Expert éminent sénior

    Avatar de François DORIN
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juillet 2016
    Messages
    2 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2016
    Messages : 2 761
    Points : 10 543
    Points
    10 543
    Billets dans le blog
    21
    Par défaut
    Citation Envoyé par r83 Voir le message
    Je n'ai pas de classes d'association dans la mesure où 1 cours = n séminaires mais 1 séminaire= 1 cours.
    Avec un MCD ou la structure des tables, on aurait pu voir cela directement

    Malheureusement, je crains que cela ne soit pas possible avec une requête linq d'initialiser la propriété SEMINAIRES de la classe Cours. Ca ne veut pas dire que tu ne peux pas le faire avec un peu de code en plus. Mais en linq seul, je crois que c'est impossible.

    Voici une solution qui devrait marcher :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    var reqCoursSemi = from c in oracleContexte.COURS
       join s in oracleContexte.SEMINAIREs on c.CODECOURS equals s.CODECOURS                           
       group s by c into g
       select new {Key = g.Key, List = g.ToList()).ToList();
     
    foreach(var g in reqCoursSemi) 
    {
      g.Key.SEMINAIRES = g.List;
    }
     
    var leCours = g.Select(x => x.Key).ToList();

  9. #9
    r83
    r83 est déconnecté
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2003
    Messages
    271
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2003
    Messages : 271
    Points : 86
    Points
    86
    Par défaut
    Bonsoir,

    J'ai fini par trouver.

    Les 2 requêtes qui marchent :
    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
    var reqCoursSemi = from c in oracleContexte.COURS.Include("SEMINAIRES")
                                       join s in oracleContexte.SEMINAIREs on c.CODECOURS equals s.CODECOURS into semis
                                       select c;
     
                    lesCours = reqCoursSemi.ToList();
     
                    foreach (var unCours in lesCours)
                    {
                        Console.WriteLine(unCours.CODECOURS + " - " + unCours.LIBELLECOURS + " - " + unCours.NBJOURS);
                        foreach (var unsemi in unCours.SEMINAIREs)
                        {
                            Console.WriteLine("\t\t" + unsemi.DATEDEBUTSEM);
                        }
                        Console.WriteLine();
                    }
    et
    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
    var reqCoursSemi = from c in oracleContexte.COURS
                                       join s in oracleContexte.SEMINAIREs on c.CODECOURS equals s.CODECOURS into semis
                                       select c;
     
                    lesCours = reqCoursSemi.ToList();
     
                    foreach (var unCours in lesCours)
                    {
                        Console.WriteLine(unCours.CODECOURS + " - " + unCours.LIBELLECOURS + " - " + unCours.NBJOURS);
                        foreach (var unsemi in unCours.SEMINAIREs)
                        {
                            Console.WriteLine("\t\t" + unsemi.DATEDEBUTSEM);
                        }
                        Console.WriteLine();
                    }
    Mon problème venait du fait que je mettais un point d'arrêt au niveau du foreach et que je regardais la liste lesCours et que je voyais ceci :

    Nom : linq_image.png
Affichages : 338
Taille : 11,4 Ko

    Je ne continuais pas l'exécution du programme.
    Je vois toujours ça, mais à l'exécution, l'affichage est bon, il a tout retrouvé. Il y a des choses qui m'échappent.
    De plus, si j'omets la clause into semis, ça marche, mais le résultat n'est pas bon, et si je remplace semis par toto, ça marche aussi.

    Merci pour vos éclaircissements.
    Cordialement

  10. #10
    Expert éminent sénior

    Avatar de François DORIN
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juillet 2016
    Messages
    2 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2016
    Messages : 2 761
    Points : 10 543
    Points
    10 543
    Billets dans le blog
    21
    Par défaut
    Hmmm, intéressant !

    Tout d'abord, tu peux marquer le sujet en résolu

    Ensuite, peux-tu me dire ce que tu utilises comme framework pour l'accès à tes données ? Entity Framework ? Quelle version ? Autre chose ?
    Car il semblerait que j'ai quelques points à approfondir sur les relations inverses et linq...

  11. #11
    r83
    r83 est déconnecté
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2003
    Messages
    271
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2003
    Messages : 271
    Points : 86
    Points
    86
    Par défaut
    Bonjour,

    Je n'ai pas marqué la discussion comme résolue car je pensais avoir encore des réponses.

    Framework 4.5.2

    Je travaille sur une base Oracle 11GXE
    Entity Framework : Oracle.ManagedDataAccess.EntityFramework 6.121.2.0

    Car il semblerait que j'ai quelques points à approfondir sur les relations inverses et linq...
    Merci beaucoup, je suis preneur d'infos et de conseils.

    Bonne journée

  12. #12
    Responsable .NET

    Avatar de Hinault Romaric
    Homme Profil pro
    Consultant
    Inscrit en
    Janvier 2007
    Messages
    4 570
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Cameroun

    Informations professionnelles :
    Activité : Consultant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2007
    Messages : 4 570
    Points : 252 372
    Points
    252 372
    Billets dans le blog
    121
    Par défaut
    Salut,

    Une explication pourrait se trouver dans le LazyLoading (Chargement différé) qu'offre Entity Framework. Lorsque le chargement différé est activé, les objets connexes sont chargés lorsqu'ils font l'objet d'un accès via une propriété de navigation.

    Dans ton cas, l'objet connexe est SEMINAIRES. De ce fait, c'est dans la seconde boucle foreach qu'Entity Framework ira cherché ce dernier. Le chargement différé sera activé par défaut si tu as utilisé les générateurs T4 pour entity framework pour générer ton modèle et tes classes.

    Peux-tu marquer la discussion comme résolue ?

  13. #13
    r83
    r83 est déconnecté
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2003
    Messages
    271
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2003
    Messages : 271
    Points : 86
    Points
    86
    Par défaut
    Merci pour ta réponse, je vais voir où trouver ce paramètre.

    Je marque la discussion résolue, mais je suis preneur d'informations.

    Cordialement

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

Discussions similaires

  1. Réponses: 4
    Dernier message: 10/11/2011, 18h33
  2. Réponses: 10
    Dernier message: 27/05/2010, 16h53
  3. Requête linq jointure
    Par oyigit dans le forum Linq
    Réponses: 5
    Dernier message: 18/03/2010, 16h02
  4. Linq - jointure avec deux conditions
    Par boby62423 dans le forum Linq
    Réponses: 1
    Dernier message: 02/04/2009, 09h51
  5. Jointure linq avec types sources différents
    Par Marsupilami_00 dans le forum Linq
    Réponses: 7
    Dernier message: 13/01/2009, 20h34

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