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 :

Comment gérer les données vides (NULL) dans la requête Linq Entity vers une BD


Sujet :

Linq

  1. #1
    Membre expérimenté
    Avatar de randriano
    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 219
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Madagascar

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 219
    Points : 1 438
    Points
    1 438
    Par défaut Comment gérer les données vides (NULL) dans la requête Linq Entity vers une BD
    Bonjour,

    Je me bloque sur une requête SQL, c'est du Linq Entity plutôt
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    Dim ListOfCampagnes As List(Of campagnes) = (From campagne In context.campagnes.Include("annonceurs").Include("secteurs") _
                                                        Where _
                                                            (campagne.Nom.Contains(argKeyWord) Or _
                                                             campagne.annonceurs.Nom.Contains(argKeyWord) Or _
                                                             campagne.secteurs.Nom.Contains(argKeyWord)) _
                                                            And _
                                                            (campagne.annonceurs.IdAnnonceur = argIdAnnonceur Or argIdAnnonceur = 0) _
                                                        Order By _
                                                            campagne.annonceurs.Nom Ascending _
                                                        Select campagne Distinct).ToList
    Comment gérer cette requête en cas de NULL dans certains champs des tables présentes? Ca crashe (NullReferenceException). Je cherche un équivalent à du LEFT JOIN en fait mais bon c'est du Linq

  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
    Pour faire un LEFT join en LINQ, il faut utiliser la fonction DefaultIfEmpty()

    Exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    var i = from a in table1 join b in table2 on a.ID = b.ID into temp
    from c in temp.DefaultIfEmpty() select c;
    avec DefaultIfEmpty(), LINQ va retourner une sequence vide au lieu de rien du tout => le le join va se faire

  3. #3
    Membre expérimenté
    Avatar de randriano
    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 219
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Madagascar

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 219
    Points : 1 438
    Points
    1 438
    Par défaut
    Merci pour le truc de DefaultEmpty mais ce qu'il me faut c'est en fait ne pas considérer les enregistrements nuls (INNER JOIN)
    Par exemple la requête suivante crashe car une ligne de ListOfBooks ayant un IdLibrary vide (FK vers la table libraries)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ListOfBooks = (From c In ListOfBooks.DefaultIfEmpty() Order By c.libraries.Name Select c).ToList

  4. #4
    Membre éprouvé Avatar de anthyme
    Homme Profil pro
    Inscrit en
    Mars 2004
    Messages
    1 559
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2004
    Messages : 1 559
    Points : 1 257
    Points
    1 257
    Par défaut
    Tu es sûr que tu n'es pas en linq to object sur cette requete ?

    Car en effet en linq to object on ne peut pas faire d'orderby avec des reference null de façon standard

  5. #5
    Membre expérimenté
    Avatar de randriano
    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 219
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Madagascar

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 219
    Points : 1 438
    Points
    1 438
    Par défaut
    J'utilise du Linq to Entities mais pas du Linq to Object mais peut que linq2entities ne permet pas aussi de faire d'orderby avec des NULL

  6. #6
    Rédacteur
    Avatar de The_badger_man
    Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2005
    Messages
    2 745
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 745
    Points : 8 538
    Points
    8 538
    Par défaut
    Citation Envoyé par randriano Voir le message
    Merci pour le truc de DefaultEmpty mais ce qu'il me faut c'est en fait ne pas considérer les enregistrements nuls (INNER JOIN)
    Par exemple la requête suivante crashe car une ligne de ListOfBooks ayant un IdLibrary vide (FK vers la table libraries)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ListOfBooks = (From c In ListOfBooks.DefaultIfEmpty() Order By c.libraries.Name Select c).ToList

    bin il suffit de rajouter un filtre avec libraries qui n'est pas null.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ListOfBooks = (From c In ListOfBooks Where c.libraries <> Null Order By c.libraries.Name Select c).ToList
    ps: je ne suis pas sur de la syntaxe en VB.NET.

  7. #7
    Membre expérimenté
    Avatar de randriano
    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 219
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Madagascar

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 219
    Points : 1 438
    Points
    1 438
    Par défaut
    En fait, ce n'est pas c.libraries qui contient des lignes vides causant l'erreur mais plutôt ListOfBooks qui contient des "Nom" vides, en fait "<> NULL" ou "IsNot Nothing"?

    Ma remarque: en cherchant dans ce forum, je n'ai pas trouvé beaucoup de gens qui utilisent des Include() comme dans mes requêtes:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Return (From a In Context.libraries.Include("sections").Include("sections.rangees").Include("sections.rangees.messages").Include("sections.rangees.messages.tarifs").Include("sections.rangees.messages.tarifs.produitsvendus").Include("sections.rangees.messages.tarifs.produitsvendus.distributions").Include("sections.rangees.messages.tarifs.produitsvendus.distributions.produits").Include("sections.rangees.messages.tarifs.produitsvendus.distributions.fournisseurs").Include("sections.rangees.messages.tarifs.produitsvendus.supports").Include("sections.rangees.messages.tarifs.produitsvendus.supports.medias").Include("sections.rangees.messages.parutions") _
                    Select a).ToList()

  8. #8
    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
    Citation Envoyé par randriano Voir le message
    Ma remarque: en cherchant dans ce forum, je n'ai pas trouvé beaucoup de gens qui utilisent des Include() comme dans mes requêtes:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Return (From a In Context.libraries.Include("sections").Include("sections.rangees").Include("sections.rangees.messages").Include("sections.rangees.messages.tarifs").Include("sections.rangees.messages.tarifs.produitsvendus").Include("sections.rangees.messages.tarifs.produitsvendus.distributions").Include("sections.rangees.messages.tarifs.produitsvendus.distributions.produits").Include("sections.rangees.messages.tarifs.produitsvendus.distributions.fournisseurs").Include("sections.rangees.messages.tarifs.produitsvendus.supports").Include("sections.rangees.messages.tarifs.produitsvendus.supports.medias").Include("sections.rangees.messages.parutions") _
                    Select a).ToList()
    Les Include() c'est très facile mais ça peut vite partir en vrille si il y en a beaucoup (comme dans ton exemple, ça doit donner un graphe enorme).
    En général, si beaucoup d'include, je préfère faire une StoreProc ou une View qui me renvoie uniquement les champs dont j'ai besoin, et faire un LINQ dessus, plutot que tout ramener.

  9. #9
    Membre expérimenté
    Avatar de randriano
    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 219
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Madagascar

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 219
    Points : 1 438
    Points
    1 438
    Par défaut
    StoreProc? Une procédure stockée au niveau du serveur

    J'ai montré ce code car en effet ça me fait une exception EntityCommandExecutionException sur certaines machines! J'ai pensé à un enregistrement vide mais la BD est la même donc je ne sais pas

    J'en profite pour demander: comment déboguer du LINQ? Voir le graphe comme tu le dis là, EquinoxeDotnet?

  10. #10
    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
    Citation Envoyé par randriano Voir le message
    StoreProc? Une procédure stockée au niveau du serveur?
    Oui. Ou alors une vue.

    Citation Envoyé par randriano Voir le message
    J'en profite pour demander: comment déboguer du LINQ? Voir le graphe comme tu le dis là, EquinoxeDotnet?
    Perso j'utilise LINQPad. C'est vrailent pratique. La version de base est gratuite, et la version payante (avec intellisense) est de 39US$, et ça les vaut largement! (Je ne sais pas si c'est toujours le cas mais quand je l'ai acheté c'etait mises à jour à vie compris! Si ça c'est pas une bonne affaire!).
    http://www.linqpad.net/
    (NOTE : Il semble que la l'intellisense de la version payante ne marche qu'avec C#)

  11. #11
    Membre expérimenté
    Avatar de randriano
    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 219
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Madagascar

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 219
    Points : 1 438
    Points
    1 438
    Par défaut
    Génial ce LinqPad, merci pour le tuyau, je le teste avec la version standalone et ça me suffit pour le moment

  12. #12
    Membre expérimenté
    Avatar de randriano
    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 219
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Madagascar

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 219
    Points : 1 438
    Points
    1 438
    Par défaut
    Je reviens sur ce sujet car j'ai encore quelques questions: est-ce que ma requête avec beaucoup d'Include() consomme de la mémoire ou nécessite beaucoup de ressource processeur? En fait, il paraît que l'erreur EntityCommandExecutionException est due au fait que le Command Timeout ne suffit plus, où peut-on élever sa valeur en dehors du code?

  13. #13
    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
    La connectionstring se trouve dans le fichier .config de ton appli. Tu peux rajouter un "Connection Timeout=XX".
    Mais il vaut mieux regarder la cause, voir si tu peux optimiser tes query.
    Avec beaucoup d'include, ca va consommer du temps DB, de la mémoire principalement. Si ça doit passer par des WCF ou autres, si va utiliser pas mal de resources en plus.

  14. #14
    Membre expérimenté
    Avatar de randriano
    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 219
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Madagascar

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 219
    Points : 1 438
    Points
    1 438
    Par défaut
    Citation Envoyé par EquinoxeDotNet Voir le message
    Avec beaucoup d'include, ca va consommer du temps DB, de la mémoire principalement..
    Du temps DB? Tu m'avais dit avant de préférer une vue ou une procédure stockée donc cela consommerait tous du temps DB, non?

    Dans le cadre d'optimisation de ma query, je rencontre une situation bizarre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    From par In parutions.Include("messages").Include("messages.tarifs").Include("messages.tarifs.formats").Include("messages.tarifs.produitsvendus.distributions.fournisseurs").Include("messages.parutions").Include("messages.tarifs.produitsvendus.supports").Include("messages.tarifs.produitsvendus.supports.medias") Where par.messages.plansmedias.IdPlanMedia = 12 And par.messages.tarifs.produitsvendus.distributions.fournisseurs.IdFournisseur = 5 And par.messages.tarifs.produitsvendus.supports.medias.IdMedia = 2 Select par
    s'exécute rapidement mais la seconde query suivante provoque un EntityCommandExecutionException:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    From par In parutions.Include("messages").Include("messages.tarifs").Include("messages.tarifs.formats").Include("messages.tarifs.produitsvendus.distributions.fournisseurs").Include("messages.parutions").Include("messages.tarifs.produitsvendus.supports").Include("messages.tarifs.produitsvendus.supports.medias") Where par.messages.plansmedias.IdPlanMedia = 12 And par.messages.tarifs.produitsvendus.distributions.fournisseurs.IdFournisseur = 5 And par.messages.tarifs.produitsvendus.supports.medias.IdMedia = 2 And par.messages.HeureParution = "7h30-7h45" Select par
    dont la différence est seulement un AND par.messages.HeureParution = "7h30-7h45"

  15. #15
    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 : 38
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Octobre 2008
    Messages : 3 615
    Points : 8 080
    Points
    8 080
    Par défaut
    Citation Envoyé par randriano Voir le message
    Du temps DB? Tu m'avais dit avant de préférer une vue ou une procédure stockée donc cela consommerait tous du temps DB, non?

    Dans le cadre d'optimisation de ma query, je rencontre une situation bizarre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    From par In parutions.Include("messages").Include("messages.tarifs").Include("messages.tarifs.formats").Include("messages.tarifs.produitsvendus.distributions.fournisseurs").Include("messages.parutions").Include("messages.tarifs.produitsvendus.supports").Include("messages.tarifs.produitsvendus.supports.medias") Where par.messages.plansmedias.IdPlanMedia = 12 And par.messages.tarifs.produitsvendus.distributions.fournisseurs.IdFournisseur = 5 And par.messages.tarifs.produitsvendus.supports.medias.IdMedia = 2 Select par
    s'exécute rapidement mais la seconde query suivante provoque un EntityCommandExecutionException:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    From par In parutions.Include("messages").Include("messages.tarifs").Include("messages.tarifs.formats").Include("messages.tarifs.produitsvendus.distributions.fournisseurs").Include("messages.parutions").Include("messages.tarifs.produitsvendus.supports").Include("messages.tarifs.produitsvendus.supports.medias") Where par.messages.plansmedias.IdPlanMedia = 12 And par.messages.tarifs.produitsvendus.distributions.fournisseurs.IdFournisseur = 5 And par.messages.tarifs.produitsvendus.supports.medias.IdMedia = 2 And par.messages.HeureParution = "7h30-7h45" Select par
    dont la différence est seulement un AND par.messages.HeureParution = "7h30-7h45"
    C'est peut être un problème d'indexation sur la table.
    Le mieux serait de prendre le profiler SQL, de regarder la requête et son plan d'execution. Tu sauras si tu fais un index lookup ou un full scan de la table. Vu la tête des données je dirais que c'est pas indexé

  16. #16
    Membre expérimenté
    Avatar de randriano
    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 219
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Madagascar

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 219
    Points : 1 438
    Points
    1 438
    Par défaut
    En effet, il n'y a pas d'index sur ce champ de type varchar

    Le bizarre selon moi c'est que sous LinqPad la durée d'exécution de ces 2 requêtes n'est que de 1 seconde!

  17. #17
    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
    Citation Envoyé par randriano Voir le message
    Du temps DB? Tu m'avais dit avant de préférer une vue ou une procédure stockée donc cela consommerait tous du temps DB, non?
    Oui mais (pour simplifier) ça prends moins de temps de faire une vue ou stored procedure optimisée que de "bêtement" tout ramener, c'est ce que je voulais dire.

Discussions similaires

  1. Réponses: 1
    Dernier message: 16/08/2014, 20h03
  2. Réponses: 6
    Dernier message: 13/05/2011, 11h21
  3. Réponses: 2
    Dernier message: 22/02/2009, 13h02
  4. Comment centraliser les données de context dans un seul fichier ?
    Par Scorpio85 dans le forum Développement de jobs
    Réponses: 3
    Dernier message: 31/07/2008, 14h37
  5. Comment gérer les valeur Nulles dans une requête ?
    Par sondo dans le forum Bases de données
    Réponses: 3
    Dernier message: 16/03/2005, 11h02

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