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

Dotnet Discussion :

LinqToSql => Manipuler le ExecuteQuery de façon générique (sans typage) [Débutant]


Sujet :

Dotnet

  1. #1
    Membre averti Avatar de dacid
    Homme Profil pro
    Inscrit en
    Juin 2003
    Messages
    1 063
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 1 063
    Points : 420
    Points
    420
    Par défaut LinqToSql => Manipuler le ExecuteQuery de façon générique (sans typage)
    Bonjour @ tous,

    Actuellement, j'utilise datareader1.read() pour charger une collection d'objet depuis une BDD.
    Suite à un besoin d'optimisation, un membre de la communauté m'a conseillé de le faire à la LinqToSql (tout charger en mémoire plutôt que de la lecture séquentielle).
    J'aimerais donc utiliser les outils de communication de EF, mais sans mettre en place tout le framework qui va avec.

    J'ai réussi à faire ça:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
            Dim dc As DataContext = New DataContext(myConnection)
            Dim objs As List(Of Object) = dc.ExecuteQuery(Of Object)(StrSql).ToList()
    Le pire, c'est que ça fonctionne, mais il me renvoie un tableau d'objects dont je ne sais quoi faire.
    Je n'ai pas réussi à la caster en quoi que ce soit que je connaisse.

    J'ai essayé de faire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
            Dim dc As DataContext = New DataContext(myConnection)
            Dim objs As List(Of DictionaryEntry) = dc.ExecuteQuery(Of DictionaryEntry)(StrSql).ToList()
    Et aussi avec un KeyValuePair(Of String, Object), mais il me fait un message d'erreur :
    "System.Collections.DictionaryEntry' doit déclarer un constructeur par défaut (sans paramètre) pour être construit lors du mappage."

    Avez vous une piste ?

    Merci d'avance.
    David.

  2. #2
    Expert éminent sénior

    Avatar de François DORIN
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juillet 2016
    Messages
    2 757
    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 757
    Points : 10 697
    Points
    10 697
    Billets dans le blog
    21
    Par défaut
    Suite à un besoin d'optimisation, un membre de la communauté m'a conseillé de le faire à la LinqToSql (tout charger en mémoire plutôt que de la lecture séquentielle).
    Non. Dans la conversation précédente, je te disais simplement que ton benchmark était erroné. Si tu voulais mesurer d'une part le temps mis pour récupérer les données et ensuite le temps mis pour les traiter, tu dois d'abord tout récupérer et ensuite les traiter. Avec le code que tu avais, dès que tu récupérais un enregistrement, tu le traitais. Du coup, dans ton temps de traitement se trouvait un temps imputable à la récupération des données.

    Pour optimiser ta tâche et savoir où se trouve le goulot d'étranglement, il vaut mieux bien séparer ces deux opérations.

    Maintenant, pour répondre à ta nouvelle question, il faut que tu aies une classe ayant :
    • des propriétés publiques ayant un nom correspondant au nom de tes colonnes lors de l'exécution de ta requête ;
    • un constructeur public et sans paramètre


    Ainsi, tu pourras écrire quelque chose comme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Dim objs As List(Of ObjetResultat) = dc.ExecuteQuery(Of ObjetResultat)(StrSql).ToList()
    où ObjetResultat est une classe qui sera instanciée automatiquement lors de l'appel à ExecuteQuery pour chaque enregistrement.
    François DORIN
    Consultant informatique : conception, modélisation, développement (C#/.Net et SQL Server)
    Site internet | Profils Viadéo & LinkedIn
    ---------
    Page de cours : fdorin.developpez.com
    ---------
    N'oubliez pas de consulter la FAQ C# ainsi que les cours et tutoriels

  3. #3
    Membre averti Avatar de dacid
    Homme Profil pro
    Inscrit en
    Juin 2003
    Messages
    1 063
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 1 063
    Points : 420
    Points
    420
    Par défaut
    Ok, je suis obligé de faire un objet intermédiaire qui ressemble beaucoup à mon objet métier donc.
    Puis de faire un mappage après.

    Mais du coup, s'il existe des attributs de propriété (comme Json un peu) qui permettent de garder mes noms (plus parlants), je vais pouvoir faire du 2 en 1, ça peut être pas mal....
    David.

  4. #4
    Expert éminent sénior

    Avatar de François DORIN
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juillet 2016
    Messages
    2 757
    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 757
    Points : 10 697
    Points
    10 697
    Billets dans le blog
    21
    Par défaut
    Citation Envoyé par dacid Voir le message
    Ok, je suis obligé de faire un objet intermédiaire qui ressemble beaucoup à mon objet métier donc.
    Puis de faire un mappage après.
    Voui

    Citation Envoyé par dacid Voir le message
    Mais du coup, s'il existe des attributs de propriété (comme Json un peu) qui permettent de garder mes noms (plus parlants), je vais pouvoir faire du 2 en 1, ça peut être pas mal....
    Tu peux regarder du côté de l'attribut Column. Mais je ne sais pas si cela marchera dans ce cas (je n'ai jamais testé).
    François DORIN
    Consultant informatique : conception, modélisation, développement (C#/.Net et SQL Server)
    Site internet | Profils Viadéo & LinkedIn
    ---------
    Page de cours : fdorin.developpez.com
    ---------
    N'oubliez pas de consulter la FAQ C# ainsi que les cours et tutoriels

  5. #5
    Membre averti Avatar de dacid
    Homme Profil pro
    Inscrit en
    Juin 2003
    Messages
    1 063
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 1 063
    Points : 420
    Points
    420
    Par défaut
    Ca fonctionne impec. :-)

    J'ai fait ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    <Mapping.Table>
    Public Class tblArticle
        Inherits tblTemplate(Of tblArticle)
    ...
        <Mapping.Column(Name:="ART", IsPrimaryKey:=True)> ' Ajout d’attribut pour mapper les propriétés
        Public Property Id() As String
        <Mapping.Column(Name:="FAB")> ' Ajout de propriétés pour récupérer les ID
        Property FabId() As String
    End Class
    Dans la méthode GetAll de ma classe tblArticles :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
            Dim dc As DataContext = New DataContext(_Env.Bases.Item(1).OpenConnection(0))
            Dim objs As List(Of tblArticle) = dc.ExecuteQuery(Of tblArticle)(StrSql).ToList()
            sb.Append($"SqlExec({DateTime.Now:mm:ss}) ")
            For Each obj As tblArticle In objs
                obj._Env = _Env
                obj.Fab = Fabs.GetById(New tblFabricant(_Env) With {.Id = obj.FabId.Trim()})
                obj.SsFam = SsFams.GetById(New tblArtSsFamille(_Env) With {.Id = obj.SsFamId.Trim(), .Fam = Fams.GetById(New tblArtFamille(_Env) With {.Id = obj.FamId.Trim()}), .Nat = Nats.GetById(New tblNature(_Env) With {.Id = obj.NatId.Trim()})})
                obj.UniStock = Unis.GetById(New tblUnite(_Env) With {.Id = obj.UniStoId.Trim()})
                obj.UniCommande = Unis.GetById(New tblUnite(_Env) With {.Id = obj.UniCdeId.Trim()})
            Next
    Et dans ma classe template :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    <Mapping.InheritanceMapping(Code:=1, IsDefault:=True, Type:=GetType(tblArticle))>
    <Mapping.Table>
    Public Class tblTemplate(Of T)
    ...
    End Class
    Je m'en serais bien passé, mais si je ne fait pas ça, j'ai cette erreur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Les données membres 'tblUser _UsrMaj' du type 'tblTemplate`1[tblArticle]' ne font pas partie du mappage pour le type 'tblArticle'. 
    Est-ce que ces données membres sont situées au-dessus de la racine d'une hiérarchie d'héritage ?
    Par contre, je n'arrive pas à récupérer le UserId, si je met un attribut "Column" dans tblTemplate, il me met :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
        <Mapping.Column(Name:="UTIMAJ")>
        Private Property UsrMajId As String
     
    Les données membres 'System.String UsrMajId' du type 'tblTemplate`1[tblArticle]' ne font pas partie du mappage pour le type 'tblArticle'. 
    Est-ce que ces données membres sont situées au-dessus de la racine d'une hiérarchie d'héritage ?
    Ca m'ennuie de le faire dans la classe tblArticle...
    David.

  6. #6
    Expert éminent sénior

    Avatar de François DORIN
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juillet 2016
    Messages
    2 757
    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 757
    Points : 10 697
    Points
    10 697
    Billets dans le blog
    21
    Par défaut
    Pour la dernière erreur, ne serait-ce pas parce que ta propriété est private ?
    François DORIN
    Consultant informatique : conception, modélisation, développement (C#/.Net et SQL Server)
    Site internet | Profils Viadéo & LinkedIn
    ---------
    Page de cours : fdorin.developpez.com
    ---------
    N'oubliez pas de consulter la FAQ C# ainsi que les cours et tutoriels

  7. #7
    Membre averti Avatar de dacid
    Homme Profil pro
    Inscrit en
    Juin 2003
    Messages
    1 063
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 1 063
    Points : 420
    Points
    420
    Par défaut
    Je me suis laissé dire qu'il le gérait bien, vu qu'il le gère bien pour la sérialisation.
    De plus, dans tblArticle, je ne met rien devant mes propriétés (donc ça équivaut à "private", non ?) et ça fonctionne.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    <Mapping.Column(Name:="FAB")>
    Property FabId() As String
    Je pense que c'est plus vicieux que ça... Mais je vais essayer.
    David.

  8. #8
    Expert éminent sénior

    Avatar de François DORIN
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juillet 2016
    Messages
    2 757
    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 757
    Points : 10 697
    Points
    10 697
    Billets dans le blog
    21
    Par défaut
    Je me suis avancé un peu vite. Effectivement, que la propriété soit privée ou publique ne change rien.

    En gros, si tu veux utiliser de l'héritage, il faut qu'au niveau de tes objets il y ait également une relation d'héritage. Or là, ce que tu souhaites, c'est pouvoir, dans une classe de base, mettre les propriétés communes sans pour autant qu'il y ait une quelconque relation entre tes objets.

    J'ai l'impression que dans ton cas, tu n'aies pas vraiment le choix : tout mettre au niveau de chaque classe.
    François DORIN
    Consultant informatique : conception, modélisation, développement (C#/.Net et SQL Server)
    Site internet | Profils Viadéo & LinkedIn
    ---------
    Page de cours : fdorin.developpez.com
    ---------
    N'oubliez pas de consulter la FAQ C# ainsi que les cours et tutoriels

  9. #9
    Membre averti Avatar de dacid
    Homme Profil pro
    Inscrit en
    Juin 2003
    Messages
    1 063
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 1 063
    Points : 420
    Points
    420
    Par défaut
    Oui, j'ai également vu un article similaire:
    https://social.msdn.microsoft.com/Fo...projectgeneral

    Bon, MIcrosoft a encore un peu de boulot à faire.

    Encore merci.
    David.

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

Discussions similaires

  1. [Hudson] [Jonas] déployer des war/ear de façon générique même si non spécifié dans le pom projet
    Par inconnu652000 dans le forum Intégration Continue
    Réponses: 7
    Dernier message: 25/11/2013, 12h37
  2. Réponses: 10
    Dernier message: 27/12/2010, 17h52
  3. Appel de méthode de façon générique
    Par eyango dans le forum Langage
    Réponses: 6
    Dernier message: 10/07/2009, 13h41
  4. Remplir un array de façon générique
    Par ragnarokr dans le forum C#
    Réponses: 7
    Dernier message: 06/03/2008, 17h04
  5. Réponses: 1
    Dernier message: 28/06/2005, 10h28

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