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 avec LEFT JOIN, agrégat et where


Sujet :

Linq

  1. #1
    Membre régulier
    Homme Profil pro
    Inscrit en
    Mars 2007
    Messages
    244
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations forums :
    Inscription : Mars 2007
    Messages : 244
    Points : 122
    Points
    122
    Par défaut Linq avec LEFT JOIN, agrégat et where
    Salut à toutes et à tous,

    Je dois avoir une erreur que je ne trouve pas dans mon LINQ, c'est pourquoi je me permet de faire appel à vous.

    Soit une table Contrats et une table temps.

    Le but est de sortir la somme du champs "Cout" de la table temps et dont le champs "Date" se situe entre 2 limites (paramètres) et dont le champs "NumContrat" vaut une valeur définie (paramètre).

    Pas de problème s'il y a des champs dans la table contrat ET dans la table champs, mais si il y a un contrat qui n'a pas de temps entre les dates définie, il ne sort pas du tout, ce qui est logique.

    Il faudrait toutefois que le contrat sorte avec un count = 0.

    J'ai dont fais un "LEFT JOIN" comme ci-dessous, mais s'il n'y a pas ligne de la table "temps" qui remplisse les conditions de date, rien ne sort. Je me dis donc que j'ai dû me tromper quelque part mais je n'arrive pas à trouver où.

    Si vous trouvez mon erreur, merci de m'expliquer quelle est cette erreur et comment la résoudre.

    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 temps = (this.MdiParent as FormPrincipal).dataSetFT.Tbl_Temps.AsEnumerable();
                    var contrats = (this.MdiParent as FormPrincipal).dataSetFT.Tbl_Contrats.AsEnumerable();
     
                    var query = from contrat in contrats
                                join temp in temps
                                on contrat.NumContrat equals temp.NumContrat into grouped
                                from subtemp in grouped.DefaultIfEmpty()
                                where (subtemp == null && contrat.NumContrat == dgvr.Cells["numContrat"].Value.ToString()) || (contrat.NumContrat == dgvr.Cells["numContrat"].Value.ToString() && subtemp.Date >= debutDateTimePicker.Value.Date && subtemp.Date <= finDateTimePicker.Value.Date)
                                group subtemp by new { NumContrat = contrat.NumContrat, Titre = contrat.Titre } into g
                                select new
                                {
                                    numContrat = g.Key.NumContrat,
                                    Titre = g.Key.Titre,
                                    CoutTotal = g.Sum(subtemp => (subtemp == null ? 0 : subtemp.Cout))
                                };
    Dans mon where je veux prendre si on a le contrat.NumContrat et que le subtemp est null (donc si c'est le bon contrat et qu'il n'y a pas de temps), ou si on a le contrat.NumContrat et que subtemp.Date est entre les limites. Toutefois, si le subtemp est null, il ne sort aucune ligne.

    Merci de vos z'avis z'avisés.
    Il n'y a pas de problèmes. Il n'y a que des solutions.
    Malheureusement, elles sont parfois un peu dur à trouver ...


    Aucune touche n'a été maltraitée pour réaliser ce texte.

  2. #2
    Membre expert
    Avatar de GuruuMeditation
    Homme Profil pro
    .Net Architect
    Inscrit en
    Octobre 2010
    Messages
    1 705
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : Belgique

    Informations professionnelles :
    Activité : .Net Architect
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2010
    Messages : 1 705
    Points : 3 568
    Points
    3 568
    Par défaut
    Quel casse-tête un vendredi matin

    Pour tester le linq, il y a LinqPad qui est génial.

    Sinon, essaye de tester ta requête petit à petit. Déjà pour voir si e problème se trouve avant ou après le Where à le ligne 8
    Microsoft MVP : Windows Platform

    MCPD - Windows Phone Developer
    MCPD - Windows Developer 4

    http://www.guruumeditation.net

    “If debugging is the process of removing bugs, then programming must be the process of putting them in.”
    (Edsger W. Dijkstra)

  3. #3
    Membre régulier
    Homme Profil pro
    Inscrit en
    Mars 2007
    Messages
    244
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations forums :
    Inscription : Mars 2007
    Messages : 244
    Points : 122
    Points
    122
    Par défaut
    Merci le Gourou méditatif ,

    J'ai installé Linkpad, et grâce à lui j'ai codé ceci :
    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 temps = (this.MdiParent as FormPrincipal).dataSetFT.Tbl_Temps.AsEnumerable();
    var contrats = (this.MdiParent as FormPrincipal).dataSetFT.Tbl_Contrats.AsEnumerable();
    var query = from contrat in contrats
                                where contrat.NumContrat == "2014-A-11429" || contrat.NumContrat == "2013-A-10703"
                                join temp in temps
                                    on contrat.NumContrat equals temp.NumContrat into grouped
                                from subtemp in grouped.DefaultIfEmpty()
                                where subtemp == null || (subtemp.Date != null && subtemp.Date >= new DateTime(2014, 4, 1) && subtemp.Date <= new DateTime(2014, 7, 1))
                                group subtemp by new { NumContrat = contrat.NumContrat, Titre = contrat.Titre } into g
                                select new
                                {
                                    numContrat = g.Key.NumContrat,
                                    Titre = g.Key.Titre,
                                    CoutTotal = g.Sum(subtemp => subtemp.Cout)
                                };
    J'y ai mis des date ainsi que 2 contrats en dur. L'un ayant des données dans les dates, l'autre pas.
    Il fonctionne bien dans LinkPad et me sort, dans LinkPad, le résultat attendu.
    Toutefois, lorsque je le roule dans mon application en C#, j'ai l'erreur "La valeur pour la colonne 'Date' dans la table 'Tbl Temps' est DBNull." lorsqu'il passe sur "subtemp.Date >= new DateTime(2014, 4, 1) && subtemp.Date <= new DateTime(2014, 7, 1)" quand subtemp.Date est null, malgré la partie de la ligne "where ... (subtemp.Date != null && ...). Je ne comprend pas du tout pourquoi puisque vu le double &, si la première condition n'est pas remplie, il n'est pas sensé continuer la vérification.

    Quelqu'un comprend-t-il pourquoi et peut-il me l'expliquer svp ?

    Merci de vos z'avis z'avisés
    Il n'y a pas de problèmes. Il n'y a que des solutions.
    Malheureusement, elles sont parfois un peu dur à trouver ...


    Aucune touche n'a été maltraitée pour réaliser ce texte.

  4. #4
    Membre expert
    Avatar de GuruuMeditation
    Homme Profil pro
    .Net Architect
    Inscrit en
    Octobre 2010
    Messages
    1 705
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : Belgique

    Informations professionnelles :
    Activité : .Net Architect
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2010
    Messages : 1 705
    Points : 3 568
    Points
    3 568
    Par défaut
    Null et DBNull sont différents

    Tu utilises des Datasets? Si je me rappelle bien, il faut alors que la colonne soit définie en nullable, et alors tu as une méthode genre IsColumnNull que tu peux appeler.
    Microsoft MVP : Windows Platform

    MCPD - Windows Phone Developer
    MCPD - Windows Developer 4

    http://www.guruumeditation.net

    “If debugging is the process of removing bugs, then programming must be the process of putting them in.”
    (Edsger W. Dijkstra)

  5. #5
    Membre régulier
    Homme Profil pro
    Inscrit en
    Mars 2007
    Messages
    244
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations forums :
    Inscription : Mars 2007
    Messages : 244
    Points : 122
    Points
    122
    Par défaut
    La colonne l'était bien mais je le déclarais mal,

    Voici le linq qui fonctionne, pour ceux que cela intéresserait :
    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 temps = (this.MdiParent as FormPrincipal).dataSetFT.Tbl_Temps.AsEnumerable();
    var contrats = (this.MdiParent as FormPrincipal).dataSetFT.Tbl_Contrats.AsEnumerable();
    var query = from contrat in contrats
                where contrat.NumContrat == dgvr.Cells["numContrat"].Value.ToString()
                join temp in temps
                    on contrat.NumContrat equals temp.NumContrat into grouped
                from subtemp in grouped.DefaultIfEmpty()
                group subtemp by new { NumContrat = contrat.NumContrat, Titre = contrat.Titre } into g
                select new
                {
                    numContrat = g.Key.NumContrat,
                    Titre = g.Key.Titre,
                    CoutTotal = (g.Sum(subtemp => (subtemp == null || (!subtemp.IsDateNull() && subtemp.Date >= debutDateTimePicker.Value.Date && subtemp.Date <= finDateTimePicker.Value.Date)) ? (double?)subtemp.Cout ?? 0 : 0))//g.Sum(subtemp => subtemp.Cout)
                };
    Merci à GuruuMeditation
    Il n'y a pas de problèmes. Il n'y a que des solutions.
    Malheureusement, elles sont parfois un peu dur à trouver ...


    Aucune touche n'a été maltraitée pour réaliser ce texte.

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

Discussions similaires

  1. Aide sur une requête LINQ avec left outer join
    Par jbrasselet dans le forum Linq
    Réponses: 5
    Dernier message: 12/09/2011, 09h31
  2. Reqête avec LEFT JOIN
    Par kirsoul dans le forum Requêtes
    Réponses: 5
    Dernier message: 26/12/2005, 18h00
  3. Plantage Mysql avec LEFT JOIN
    Par verticka dans le forum Requêtes
    Réponses: 2
    Dernier message: 01/09/2005, 11h45
  4. requete avec left join et group by
    Par slc dans le forum Requêtes
    Réponses: 2
    Dernier message: 14/09/2004, 18h03
  5. Export d'une vue avec LEFT JOIN
    Par schnourf dans le forum MS SQL Server
    Réponses: 3
    Dernier message: 22/05/2003, 13h57

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