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

C# Discussion :

Requete SQL avec jointure vers Objet


Sujet :

C#

  1. #1
    Membre à l'essai
    Femme Profil pro
    Développeur .NET
    Inscrit en
    Octobre 2014
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 40
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Octobre 2014
    Messages : 9
    Points : 20
    Points
    20
    Par défaut Requete SQL avec jointure vers Objet
    Bonjour,

    je recherche la meilleur pratique pour gérer les résultats des jointures SQL dans des objets. Actuellement, je travaille de la façon suivante :

    Pour chaque table :
    Je crée une classe chargée de mapper les champs de la table à des propriétés.
    Je crée une classe service contenant les requetes SQL.

    Pour illustrer simplement :
    Ma BDD a deux tables : Marchandise et TypeMarchandise. Je crée donc 4 classes :
    Classes de la table Marchandise :
    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
    17
    18
    19
    20
     
        public class Marchandise
        {
     
            public string Code { get; set; }
            public short Quantite { get; set; }
            public decimal Poids { get; set; }
     
     
            /// <summary>
            /// Constructeur lors d'un select
            /// </summary>
            /// <param name="r"></param>
            public Marchandise(IDataReader r)
            {
                Code = (r["CodeMarch"] as string)?.Trim() ?? "0";
                Quantite = (short)r["QttMarch"];
                this.Poids = (decimal)r["PoidsMarc"];
            }
        }
    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 class MarchandiseService
        {
            public Marchandise Get(string code, IDbConnection db)
            {
                var cmd = db.CreateCommand();
                Marchandise result = null;
                cmd.CommandText = $"SELECT * FROM MARCHANDISE WHERE CODE = {code}";
                using (IDataReader r = cmd.ExecuteReader())
                {
                    if (r.Read())
                        result = new Marchandise(r);
                }
                return result;
            }
        }

    Classes de la table TypeMarchandise :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
        public class TypeMarchandise
        {
     
     
            public string Code { get; set; }
            public string Libelle { get; set; }
     
            public TypeMarchandise(IDataReader r)
            {
                Code = (r["CodeMarch"] as string)?.Trim() ?? "0";
                Libelle = (r["LibelleMarch"] as string)?.Trim() ?? "Non renseigné";
            }
        }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
            public TypeMarchandise Get(string code, IDbConnection db)
            {
                var cmd = db.CreateCommand();
                TypeMarchandise result = null;
                cmd.CommandText = $"SELECT * FROM TYPEMARCHANDISE WHERE CODE = '{code}'";
                using (IDataReader r = cmd.ExecuteReader())
                {
                    if (r.Read())
                        result = new TypeMarchandise(r);
                }
                return result;
            }
        }
    Actuellement, si j'ai besoin pour mon traitement d'avoir un objet avec les propriétés de la classe Marchandise et le libellé de cette dernière, je fais :

    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
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
     
    public void test()
            {
                IDbConnection db = new SqlConnection();
     
                using (db)
                {
                    db.Open();
                    string codeMarch = "toto";
                    //Instanciation des classes services
                    MarchandiseService srvMarch = new MarchandiseService();
                    TypeMarchandiseService srvTypeMarch = new TypeMarchandiseService();
     
                    //Récupère les data en BDD
                    Marchandise march = srvMarch.Get(codeMarch, db);
                    TypeMarchandise typeMarch = srvTypeMarch.Get(codeMarch, db);
     
                    MarchandiseAvecLibelle marchEtLib = new MarchandiseAvecLibelle
                    {
                        Code = march.Code,
                        Poids = march.Poids,
                        Quantite = march.Quantite,
                        Libelle = typeMarch.Libelle
                    };
                }
            }
    Dans ce cas, je suis obligé de faire 2 requêtes SQL pour avoir mon objet final.
    Pour optimiser cela, il serait bien plus simple de faire une jointure effectuant la requête :
    "SELECT * FROM MARCHANDISE as a INNER JOIN TYPEMARCHANDISE as b ON a.CODE = b.CODE"

    Cependant, si je garde ma logique de 1 table = 1 classe objet et 1 classe service, je ne vois pas comment gérer efficacement les jointures.
    Dans cet exemple, il est simple de créer un objet spécialement pour la jointure telle que l'objet MarchandiseEtLibelle.
    Mais dans le cadre de mon développement, les jointures peuvent être multiples et elles peuvent concerner des dizaines de champs.

    J'avais pour but de ne pas avoir de requête dans mon traitement autre que les requêtes effectuées par mes classes "Service" mais, à moins de faire autant de classes objet / service que de jointure, je ne vois pas comment faire ...

    Quelle serait la meilleur pratique pour gérer cela ?

    Merci d'avance pour vos conseils.

  2. #2
    Membre éprouvé Avatar de Momoth
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mars 2013
    Messages
    318
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2013
    Messages : 318
    Points : 1 236
    Points
    1 236
    Par défaut
    Salut,

    Dans ta classe marchandise, tu peux rajouter une propriété de liaison de type "TypeMarchandise" et ensuite modifier ton mapping et ta requête.

    Edit : Je suis pas sur de la modélisation de tes tables par contre. Code est dans les deux tables la clé primaire c'est ça ? Si tu fais la jointure dessus, ça veut dire que tu as du 1-1 en type de relation ? Cela me paraîtrait plus logique de rajouter une propriété "CodeTypeMarchandise" dans la table Marchandise qui fait référence au Code de TypeMarchandise.
    La Triforce du développement : Fainéantise, Curiosité et Imagination.

  3. #3
    Membre à l'essai
    Femme Profil pro
    Développeur .NET
    Inscrit en
    Octobre 2014
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 40
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Octobre 2014
    Messages : 9
    Points : 20
    Points
    20
    Par défaut
    Bonjour Momoth,

    Merci pour votre réponse et la solution proposée.
    J'avais pensé à cette solution cependant, elle ne collait pas à la logique que j'avais implémenté jusqu'à maintenant.
    Je n'avais pas anticipé ce problème des jointures.
    Je vais repenser ma façon de faire.

    Concernant le problème que vous avez soulevé à propos de la modélisation des tables, effectivement j'aurais dû ajouter un "CodeTypeMarchandise" dans la classe "Marchandise". J'ai écrit ce bout de code vite fait pour illustrer le problème et j'ai oublié ce petit point

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

Discussions similaires

  1. Réponses: 0
    Dernier message: 02/03/2011, 23h26
  2. requete T-sql avec jointures
    Par evan_2008 dans le forum Développement
    Réponses: 3
    Dernier message: 06/03/2009, 18h24
  3. Requete SQL avec jointure sur trois tables
    Par pit2121 dans le forum Langage SQL
    Réponses: 1
    Dernier message: 19/05/2008, 23h07
  4. Requete SQL avec jointure multiple
    Par kissskoool dans le forum Langage SQL
    Réponses: 5
    Dernier message: 20/01/2008, 01h07
  5. Réponses: 5
    Dernier message: 03/09/2007, 13h52

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