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

Silverlight Discussion :

faire un join en linq


Sujet :

Silverlight

  1. #1
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    876
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Novembre 2005
    Messages : 876
    Par défaut faire un join en linq
    Bonjour,

    D'abord, pour les grincheux, je poste cette question dans le forum Silverlight car comme vous le remarquerez, j'ai besoin d'un Include, et dans tous les exemples que je trouve, le Include n'y figure pas.

    Le code ci-après fonctionne, mais je me dis qu'il doit y avoir plus simple et plus efficace... donc si quelqu'un à une idée, elle est la bienvenue.

    Voici le problème:
    J'ai des "Contrats", ces contrats contiennent un ou plusieurs "Projets". Ces contrats contiennent également une ou plusieurs "Affectations".

    Ma requête vise à récupérer tous les "projets" pour lesquels le contrat parent contient une "affectation" répondant à un certain critère.

    Voici mon 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
     public IQueryable<ProjetTbl> GetProjetsOrderedByNom(int parEmployeId)
            {
                IQueryable<ProjetTbl> aaa = default(IQueryable<ProjetTbl>);
     
     
                var itemQuery = from myAffectation in this.ObjectContext.AffectationTbl 
                    where myAffectation.AffectationEmployeId == parEmployeId 
                    select myAffectation.AffectationContratId;
     
                aaa = from myProjet in this.ObjectContext.ProjetTbl.Include("ContratTbl")
                      where itemQuery.Contains<int>( myProjet.ProjetContratId)
                          orderby myProjet.ProjetNom 
                      select myProjet;
     
                return aaa;
            }

  2. #2
    Rédacteur
    Avatar de Nathanael Marchand
    Homme Profil pro
    Expert .Net So@t
    Inscrit en
    Octobre 2008
    Messages
    3 615
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Expert .Net So@t
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2008
    Messages : 3 615
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    from projet in this.ObjectContext.ProjetTbl.Include("ContratTbl")
    where projet.contrat.affectation.lechamp = lateteatoto
    order by projet.ProjetNom
    select projet

  3. #3
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    876
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Novembre 2005
    Messages : 876
    Par défaut
    Bonjour Nathanael et merci pour ta réponse,

    Pour remettre ta suggestion dans mon code, j'ai fais:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    aaa = from myProjet in this.ObjectContext.ProjetTbl.Include("ContratTbl.AffectationTbl")
                      where myProjet.ContratTbl.AffectationTbl.AffectationEmployeId == parEmployeId
                      orderby myProjet.ProjetNom
                      select myProjet;
     
                return aaa;
    Le problème c'est que quand je charge un "Projet", je peux bien lui trouver son parent le "Contrat" grâce à l'Include, mais pas les enfants du "Contrat" qui sont mes "Affectations".

    L'intellisense me propose d'ailleurs "where myProjet.ContratTbl" mais pas "where myProjet.ContratTbl.AffectationTbl".

    Et ça me parrait logique puisque le Include ne fonctionne que quand il y a une ForeignKey et du sens enfant vers parent.

    Ne faut-il pas chercher plutôt du coté d'un Join ?

  4. #4
    Rédacteur
    Avatar de Nathanael Marchand
    Homme Profil pro
    Expert .Net So@t
    Inscrit en
    Octobre 2008
    Messages
    3 615
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Expert .Net So@t
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2008
    Messages : 3 615
    Par défaut
    Alors c'est ton modèle qui est mal fait. J'ai hésité à le mettre dans le premier message mais le Include n'est pas destiné à ca.

  5. #5
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    876
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Novembre 2005
    Messages : 876
    Par défaut
    Alors là, mon monde s'effondre...

    Si j'ai une table Pays et une table Individu

    Pays contient:

    pID pNom

    1 France
    2 Canada
    3 Belgique

    Individu contient:

    iID iNom iPaysId

    1 Philippe 1
    2 Jan 3

    J'ai donc Philippe qui est français et Jan qui est belge.
    J'ai bien une Foreign Key entre iPaysId et pID.

    Et bien pour pouvoir afficher dans un datagrid (ou ailleurs) l'entité Individu avec le pays en toutes lettres, je dois faire un:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    public IQueryable<Individu> GetIndividuAvecPays()
            {
               return  from myIndividu in this.ObjectContext.Individu.Include("Pays")
               select myIndividu;
            }
    Alors seulement je pourrai retourner Individu.iNom et aussi, grâce à l'include, Individu.Pays.pNom.

    Si le modèle n'est pas bon, comment le ferrais-tu ?

  6. #6
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    876
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Novembre 2005
    Messages : 876
    Par défaut
    Bon le code suivant qui est plus simple fonctionne avec un inconvénient de taille:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    aaa = from myProjet in this.ObjectContext.ProjetTbl.Include("ContratTbl")
                      join m in this.ObjectContext.AffectationTbl.Include("ContratTbl")
                      on myProjet.ContratTbl.ContratID equals m.ContratTbl.ContratID
                      where m.AffectationEmployeId==parEmployeId
                      select myProjet; 
                return aaa;
    Il me retourne bien uniquement les projets des contrats qui ont une affectation pour un employé déterminé.

    Il reste un Hic, c'est que malgré mes deux Include, l'entité ContratTbl de chacun des projets retournés est null.

    Pourquoi ?

    Pour ceux qui voudraient bien comprendre le modèle, voici une petite description en français:

    J'ai un contrat1 et un contrat2.
    L'employé 33, Jacques est affecté seulement au contrat2.
    J'ai donc une affectation qui reprend l'ID du contrat2 et l'ID de Jacques.
    J'ai 3 projets sur mon contrat1
    c1_1
    c1_2
    c1_3

    J'ai 2 projets sur mon contrat2
    c2_4
    c2_5

    Mon but est de ramener les projets des contrats sur lesquels Jacques est affecté. Dans ce cas, je dois ramener c2_4 et c2_5.

  7. #7
    Rédacteur
    Avatar de Nathanael Marchand
    Homme Profil pro
    Expert .Net So@t
    Inscrit en
    Octobre 2008
    Messages
    3 615
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Expert .Net So@t
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2008
    Messages : 3 615
    Par défaut
    Citation Envoyé par Golzinne Voir le message
    Alors seulement je pourrai retourner Individu.iNom et aussi, grâce à l'include, Individu.Pays.pNom
    Certes! Mais si tu veux tous les individus de France sans afficher le pays dans lequel ils sont, ceci marche tout à fait:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    from myIndividu in this.ObjectContext.Individu
    where myIndividu.Pays == "France"
    select myIndividu;
    Le Include ne doit être utilisé uniquement si tu veux que les objets dépendants soient instanciés en C#

    Pour ta requête, tu fais bien de préciser le modèle!
    Essaie un truc du genre:
    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    from projet in this.ObjectContext.ProjetTbl.Include("ContratTbl")
    where projet.contrat.affectations.Any(affectation=>affectation.employe.id == lateteatoto)
    order by projet.ProjetNom
    select projet

  8. #8
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    876
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Novembre 2005
    Messages : 876
    Par défaut
    Citation Envoyé par Nathanael Marchand Voir le message
    Certes! Mais si tu veux tous les individus de France sans afficher le pays dans lequel ils sont, ceci marche tout à fait:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    from myIndividu in this.ObjectContext.Individu
    where myIndividu.Pays == "France"
    select myIndividu;
    Le Include ne doit être utilisé uniquement si tu veux que les objets dépendants soient instanciés en C#

    Pour ta requête, tu fais bien de préciser le modèle!
    Essaie un truc du genre:
    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    from projet in this.ObjectContext.ProjetTbl.Include("ContratTbl")
    where projet.contrat.affectations.Any(affectation=>affectation.employe.id == lateteatoto)
    order by projet.ProjetNom
    select projet
    Merci pour ton aide

    Pour le premier point,

    le code doit être

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    where myIndividu.iPaysId== paramPaysId
    mais celà n'a pas d'intérêt pour moi si je n'affiche pas le pays en toutes lettres.

    Pour le second point, ça fonctionne !

    mon code définitif est:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    public IQueryable<ProjetTbl> GetProjetsOrderedByNom(int parEmployeId)
            {
                IQueryable<ProjetTbl> aaa = default(IQueryable<ProjetTbl>);
     
                aaa = 
            from projet in this.ObjectContext.ProjetTbl.Include("ContratTbl")
    where projet.ContratTbl.AffectationTbl.Any(affectation=>affectation.AffectationEmployeId == parEmployeId)
            select projet;
                return aaa;
            }
    court et propre ...

    Entretemps, j'avais également trouvé:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
            public IQueryable<ProjetTbl> GetProjetsOrderedByNom(int parEmployeId)
            {
                IQueryable<ProjetTbl> aaa = default(IQueryable<ProjetTbl>);
     
                aaa =
            ((from myProjet in this.ObjectContext.ProjetTbl
              from aff in this.ObjectContext.AffectationTbl
              where aff.AffectationEmployeId == parEmployeId && aff.AffectationContratId == myProjet.ProjetContratId
              select myProjet) as ObjectQuery<ProjetTbl>).Include("ContratTbl");
                return aaa;
            }
    qui fonctionne aussi car on met le include après avoir fait le select.

    Il y a pas mal de posts qui indiquent qu'il y a un conflit entre le Include et le Join, un des meilleurs lien est:
    http://blogs.msdn.com/b/alexj/archiv...y-include.aspx

    Mais ta solution me plait encore plus. Merci

  9. #9
    Rédacteur
    Avatar de Nathanael Marchand
    Homme Profil pro
    Expert .Net So@t
    Inscrit en
    Octobre 2008
    Messages
    3 615
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Expert .Net So@t
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2008
    Messages : 3 615
    Par défaut
    N'oublie pas de mettre le post en

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

Discussions similaires

  1. Comment faire un IN ("") en LINQ
    Par Seth_75 dans le forum Linq
    Réponses: 8
    Dernier message: 27/06/2014, 09h54
  2. Faire un remote join en LINQ
    Par yozart dans le forum Linq
    Réponses: 1
    Dernier message: 11/10/2012, 14h37
  3. Cross join en Linq
    Par Abdellah2010 dans le forum Linq
    Réponses: 1
    Dernier message: 22/02/2012, 14h13
  4. Join multiple linq et dataset
    Par bob633 dans le forum Linq
    Réponses: 9
    Dernier message: 18/10/2011, 16h39
  5. Comment faire un JOIN récursif d'une table sur elle-même?
    Par PierreCaron dans le forum Requêtes
    Réponses: 2
    Dernier message: 06/04/2009, 03h28

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