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

ASP.NET Discussion :

objectdatasource, affichage des données et 3-Tiers


Sujet :

ASP.NET

  1. #1
    Membre averti
    Inscrit en
    Février 2004
    Messages
    58
    Détails du profil
    Informations forums :
    Inscription : Février 2004
    Messages : 58
    Par défaut objectdatasource, affichage des données et 3-Tiers
    Bonjour bonjour!

    A partir d'une couche métier développée dans un autre outil et langage que Visual Studio, je souhaite trouver la meilleure méthode pour afficher mes données.

    En gros, voici à l'heure actuelle où j'en suis:
    • Je construis mes objets métier (en Powerbuilder), j'execute une requête dans ceux-ci (oui pas de couche d'accès aux données, on verra plus tard...) et je charge les données dans une collection powerbuilder. Je construis ensuite des méthodes d'accès aux informations telles que:
      • getNbColumns() pour retourner le nombre de champs liés à la requete,
      • getcolumnname(int i) pour retourner le nom d'une colonne,
      • getchampnumber(int i, int j) pour retourner le contenu du champs ligne i colonne j s'il est de type numérique
      • ...
    • Je déploie cet objet sous forme d'assembly .NET (DLL)
    • Je référence ma dll dans visual studio
    • Je construis ensuite un "wrapper" ou "proxy" (je ne sais pas comment vous appellez çà) en .NET, qui instancie cet objet métier, et qui offre une méthode getDataSet qui construit un DataSet à partir des méthodes de mon objet métier.
    • Je pose ensuite un objectdatasource, et lie le SelectMethod à la méthode getDataSet de mon proxy.
    • Je pose ensuite ma grille, et lie cette grille à l'objectdatasource.


    Bon, ok, çà marche. On est bien dans une architecture 3-tiers, et on désire le rester.
    Maintenant je voudrais savoir:
    • Ma requête SQL de mon objet métier est du style : "SELECT * FROM client". Comment je fait pour n'afficher QUE le code du client, son nom et son prénom? Plusieurs méthodes sont possibles, mais quelle est la meilleure:
      • passer un paramètre à ma méthode getDataSet, genre un tableau de chaines, comprenant la liste des champs que je veux afficher? Ensuite dans le code, je ne met dans mon dataset que les colonnes passées en paramètre. Au passage, je ne sais pas comment définir un tableau dans le SelectParameter...
      • dire tant pis à la belle architecture 3-tiers, et passer la requête SQL dans l'instanciation de l'objet métier? C'est moche, mais c'est le plus simple.
      • Faire une méthode getDataSet différente, ou faire une méthode d'initialisation de mon objet métier différente, à chaque fois que je dois faire un affichage différent?
    • L'objectdatasource ne permet pas d'avoir une actualisation de la gridview (ce qui est normal). Comment je peux faire pour "simplement", redimensionner mes colonnes, ou en virer une si besoin? Du code obligatoire?
    • L'objectdatasource est-il la meilleure solution? Est-il plus intéressant de passer par un remplissage de grille "à la main" ? Si c'est le cas, vous n'avez pas fini de me voir sur les forums...


    Je suppose que je ne suis pas le seul à avoir été confronté à ce problème...
    En fait, tout çà n'est qu'un début. Le but est de migrer beaucoup d'objets, il nous faut donc quelque chose qui soit simple à mettre en place, générique, et qui respecte au "maximum" les concepts...

    Je sais que parfois j'ai un peu de mal à m'expliquer, donc n'hésitez pas à me le faire savoir si vous n'avez rien compris.

    Merci d'avance.

  2. #2
    Membre émérite Avatar de neptune
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    835
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Novembre 2003
    Messages : 835
    Par défaut
    Citation Envoyé par Gladiator Voir le message
    [*]Ma requête SQL de mon objet métier est du style : "SELECT * FROM client". Comment je fait pour n'afficher QUE le code du client, son nom et son prénom? Plusieurs méthodes sont possibles, mais quelle est la meilleure:
    [LIST][*]passer un paramètre à ma méthode getDataSet, genre un tableau de chaines, comprenant la liste des champs que je veux afficher? Ensuite dans le code, je ne met dans mon dataset que les colonnes passées en paramètre. Au passage, je ne sais pas comment définir un tableau dans le SelectParameter...
    A ta place, je ferai ceci. Deux méthodes surchargées de getDataSet, une sans argument, et l'autre avec arguments variables. Pour garder l'abastraction de la couche Data, les arguments variables seront de type Enum, pour au final avoir un code comme celui-ci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    public enum Column
    {
      All,
      Code,
      FirstName,
      LastName,
      Sex,
      Street,
    ...
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    DateSet ds = myobject.getDataSet(Column.Code, Column.FirstName, Column.LastName);
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    public DataSet getDataSet()
    {
      return getDataSet(Column.All);
    }
     
    public DataSet getDataSet(params Column columns[])
    {
      foreach (Column col in columns)
      {
        // construction de la requete sql avec un StringBuilder ou un SqlCommandBuilder
      }
    }

  3. #3
    Membre averti
    Inscrit en
    Février 2004
    Messages
    58
    Détails du profil
    Informations forums :
    Inscription : Février 2004
    Messages : 58
    Par défaut
    Merci, je crois comprendre le principe mais j'ai du mal à l'implémenter.
    Voici mon code:

    Cette classe est une classe parente, elle sert à déclarer mes méthodes de proxy:

    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
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
     
    public class AssemblyProxy
    {
        nvo_base objet;
        public nvo_base Objet
        {
            get { return objet; }
            set { objet = value; }
        }
     
     
        public AssemblyProxy() {}
        public AssemblyProxy(nvo_base _objet) 
        {
            objet = _objet;        
        }
     
     
        public long getNbElements()
        {
            return objet.of_getrowcount();
        }
     
        public Type conversionType(string type) 
        {
            int ll_pos = type.IndexOf("(");
            if (ll_pos > 0) type = type.Substring(0,ll_pos);
            switch (type) {
                case "decimal": return System.Type.GetType("System.Int32"); 
                case "char": return System.Type.GetType("System.String"); 
                case "datetime": return System.Type.GetType("System.DateTime");
                default: return System.Type.GetType("System.String"); 
            }
        }
     
        public object recupereChamp(int ligne, int colonne)
        {
            string type = objet.of_getcolumntype(colonne);
            int ll_pos = type.IndexOf("(");
            if (ll_pos > 0) type = type.Substring(0,ll_pos);
            switch (type)
            {
                case "decimal": return objet.of_getchampnumber(ligne,colonne);
                case "char": return objet.of_getchampstring(ligne, colonne);
                case "datetime": return objet.of_getchampdate(ligne, colonne);
                default: return null;
            }
        }
     
        public string nomChamp(int colonne)
        {
            string nomChamp = objet.of_getcolumnname(colonne);
            int ll_pos = nomChamp.IndexOf(".");
            if (ll_pos > 0) nomChamp = nomChamp.Substring(ll_pos + 1);
            return nomChamp;
        }
     
     
        public DataSet getDataSet()
        {
     
            DataSet ds = new DataSet();
            ds.Tables.Add(new DataTable());
     
            //Création des colonnes
            DataColumn column;
            for (int i = 1; i <= objet.of_getnbcolumns(); i++) {
                column = new DataColumn(nomChamp(i), conversionType(objet.of_getcolumntype(i)));
                ds.Tables[0].Columns.Add(column);
            }
     
            // Création des lignes
            DataRow row;
            for (int i = 0; i < objet.of_getrowcount(); i++)
            {
                row = ds.Tables[0].NewRow();
                for (int j = 1; j <= objet.of_getnbcolumns(); j++)
                {
                    row[nomChamp(j)] = recupereChamp(i, j);
                }
                ds.Tables[0].Rows.Add(row);
            }
            return ds;
        }
     
    }
    nvo_base est un composant Powerbuilder externe parent, contenant toutes les méthodes of_getnbcolumns(), of_getchampnumber()...
    nvo_client est un composant Powerbuilder externe héritant de nvo_base. Il hérite de toutes les méthodes spécifiques à nvo_base, et contient en plus une méthode of_init() se chargeant d'exécuter une requête SQL type "SELECT * FROM client".


    Cette classe est spécifique à la gestion d'un objet métier (ici, client):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    public class ProxyClient : AssemblyProxy
    {
    	public ProxyClient()
    	{
                Objet = new nvo_client();
                Objet.of_init();
    	}
     
    }
    Je lie par wizard l'objectdatasource à ma méthode getDataSet() de l'objet ProxyClient.

    Ou dois-je déclarer mon enum? Les colonnes nom, prenom... sont propres à l'objet client, je ne dois donc pas les mettre dans AssemblyProxy. Pourtant ma méthode getDataSet() est dans AssemblyProxy. Je suis un tout petit peu pomé... çà se voit?

    Que dois-je mettre dans le choix du "SelectParameter" de mon objetdatasource pour faire intervenir un enum des colonnes que je veux afficher??

    Merci d'avance, encore.

  4. #4
    Membre émérite Avatar de neptune
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    835
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Novembre 2003
    Messages : 835
    Par défaut
    Ah oui, je vois, j'ai pas le temps maintenant mais je rejette un oeil à tout ca demain si tu veut. Je n'avais pas vu que c'etait de l'asp.net dans ma première réponse et que tu faisais du binding. Ma solution doit rester valable pourtant.

    Je reviens vers toi demain.

  5. #5
    Membre averti
    Inscrit en
    Février 2004
    Messages
    58
    Détails du profil
    Informations forums :
    Inscription : Février 2004
    Messages : 58
    Par défaut
    Merci à toi!
    Au passage, juste une petite information, je développe actuellement en ASP.NET, mais je vais appliquer le même principe sur des application WinForms C# un peu plus tard. J'ai donc besoin d'une solution qui peut s'appliquer aux deux (avec un peu de modifs si besoin, je suis pas une grosse feignasse non plus )

  6. #6
    Membre émérite Avatar de neptune
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    835
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Novembre 2003
    Messages : 835
    Par défaut
    Après avoir relu tout çà, je vais revenir un peu en arrière. La première solution donnée est intéressante, mais cassera le layering. En effet, meme si on pouvais utiliser l'enum coté asp.net, on mélangerais la couche présentation de la couche business.

    Si tu identifies dans tes besoins d'avoir une fois un dataset complet, et une fois un dataset avec code, nom, prénom; le mieux serait peut etre d'avoir:
    - getFullDataSet
    - getTinyDataSet

    Ou quelquechose comme çà ;-)

  7. #7
    Membre averti
    Inscrit en
    Février 2004
    Messages
    58
    Détails du profil
    Informations forums :
    Inscription : Février 2004
    Messages : 58
    Par défaut
    Donc tu préconise une méthode getDataSet() différente pour chaque affichage différent.
    Aucun moyen de passer une collection, un tableau dans un selectParameter d'un objectdatasource??

  8. #8
    Membre émérite Avatar de neptune
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    835
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Novembre 2003
    Messages : 835
    Par défaut
    Ma dernière expérience en asp.net remonte un peu, mais il me semble que les paramètres passés dans le SelectParameters correspondent directement à des paramètres SQL, ce qui empêche une séparation bien claire de tes couches.

    Je pense également qui si tu dois retourner plus de 2 datasets différents il faudra trouver une meilleure solution.

  9. #9
    Membre averti
    Inscrit en
    Février 2004
    Messages
    58
    Détails du profil
    Informations forums :
    Inscription : Février 2004
    Messages : 58
    Par défaut
    Non, c'est un objectdatasource. Il n'y a pas de relation avec SQL.
    Par ex, quand tu choisis une méthode getDataSet() pour récupérer tes données, un paramètre de type int dans le SelectParameter, il s'attend à trouver dans ton objet métier une méthode : Dataset getDataSet(int toto)

    Il n'associe pas ton SelectParameter à une requête SQL, il ne le peut pas puisqu'il n'y a pas de connexion à une quelconque base côté ASP.

    Je dois donc pouvoir lui passer ce que je veux, mais je ne sais pas comment lui passer un tableau. Et encore, je ne sais même pas si c'est la meilleure solution. Que ce soit le fait de passer en paramètre les colonnes que je veux afficher à ma méthode getDataSet (sous forme de tableau par exemple), ou le fait de faire plusieurs méthodes getDataSet, j'ai vraiment l'impression que c'est de la bricole!

  10. #10
    Membre émérite Avatar de neptune
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    835
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Novembre 2003
    Messages : 835
    Par défaut
    Voila, j'ai fait un test rapide, et visiblement asparameter n'autorise pas de passer autre chose que les types de base. Et là où je suis déçu c'est qu'il n'interprète pas correctement le fait que la méthode getDataSet accepte un nombre variable d'argument.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    public DataSet GetDataSet(params string[] columns)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    <SelectParameters>
                    <asp:Parameter DefaultValue="ID" Name="cols" Type="String" />
                    <asp:Parameter DefaultValue="Name" Name="cols" Type="String" />
                    ...
                </SelectParameters>
    Ne fonctionne pas, ou alors j'ai loupé quelquechose. Je cherche encore car la solution de passer un object pour alors une string avec les noms des colonnes délimitées par un séparateur ne me plait pas trop.

  11. #11
    Membre averti
    Inscrit en
    Février 2004
    Messages
    58
    Détails du profil
    Informations forums :
    Inscription : Février 2004
    Messages : 58
    Par défaut
    Non, effectivement c'est un peu de la bricole
    Et comme nous en sommes aux prémices d'un projet à long terme, il faut mieux éviter de partir sur un truc comme çà... Je ne sais pas ce qui est préconisé dans les concepts d'une archi 3 Tiers, quelqu'un s'est déjà forcément posé la question non ??

  12. #12
    Membre émérite Avatar de neptune
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    835
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Novembre 2003
    Messages : 835
    Par défaut
    Maintenant, libre à toi d'ajouter une couche de ScreenEntities au dessus des BusinessEntities. Ces objets de présentation ne contiendraient que les données utiles à l'affichage.

    Au pire, tu récupères toutes les données et tu n'affiches pas les colonnes non nécessaires.

  13. #13
    Membre averti
    Inscrit en
    Février 2004
    Messages
    58
    Détails du profil
    Informations forums :
    Inscription : Février 2004
    Messages : 58
    Par défaut
    Oui, mais justement comment le faire? En passant par une autre couche?
    Parceque je n'ai aucun moyen de le faire "graphiquement" directement sur ma grille?

  14. #14
    Membre émérite Avatar de neptune
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    835
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Novembre 2003
    Messages : 835
    Par défaut
    Citation Envoyé par Gladiator Voir le message
    Oui, mais justement comment le faire? En passant par une autre couche?
    Parceque je n'ai aucun moyen de le faire "graphiquement" directement sur ma grille?
    Pour afficher ou masquer des colonnes?

  15. #15
    Membre averti
    Inscrit en
    Février 2004
    Messages
    58
    Détails du profil
    Informations forums :
    Inscription : Février 2004
    Messages : 58
    Par défaut
    Eh bien masquer par exemple... Si j'ai une méthode getDataSet générale qui récupère tout, comment faire pour n'afficher que le nom et le prénom? Graphiquement c'est impossible?

  16. #16
    Membre émérite Avatar de neptune
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    835
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Novembre 2003
    Messages : 835
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    <asp:GridView ID="GridView1" runat="server" DataSourceID="ObjectDataSource1" AutoGenerateColumns="False">
                <Columns>
                    <asp:BoundField DataField="ID" HeaderText="ID" />
                    <asp:BoundField DataField="LastName" HeaderText="Last Name" />
                </Columns>
            </asp:GridView>
            <asp:ObjectDataSource ID="ObjectDataSource1" runat="server" SelectMethod="GetDataSet"
                TypeName="MyData">
            </asp:ObjectDataSource>

  17. #17
    Membre averti
    Inscrit en
    Février 2004
    Messages
    58
    Détails du profil
    Informations forums :
    Inscription : Février 2004
    Messages : 58
    Par défaut
    Impeccable... En plus il est possible de le faire graphiquement en par l'écran de la propriété "columns(Collection)" de la gridview. Suffit de désactiver la génération automatique des colonnes.

    En fait, c'était tout simple
    Beaucoup de bataille pour rien!

    Merci beaucoup!

  18. #18
    Membre émérite Avatar de neptune
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    835
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Novembre 2003
    Messages : 835
    Par défaut
    Oui et non, ton résultat est le bon, mais d'un point de vue performance, on n'est pas sortit de l'auberge.

    Imagine un dataset avec 50 colonnes dont tu ne veux afficher que les 3 plus utiles à ton écran? D'ou mon idée des Screen entities.

  19. #19
    Membre averti
    Inscrit en
    Février 2004
    Messages
    58
    Détails du profil
    Informations forums :
    Inscription : Février 2004
    Messages : 58
    Par défaut
    Ce serait donc une classe héritant de mon proxy et implémentant N méthode getDataSet pour chaque affichage différent?

  20. #20
    Membre averti
    Inscrit en
    Février 2004
    Messages
    58
    Détails du profil
    Informations forums :
    Inscription : Février 2004
    Messages : 58
    Par défaut
    J'pense à un truc, peut-être complètement débile...
    Si je lui fixe les colonnes à afficher dans le gridview, et qu'ensuite si je lui passe mon objet GridView en paramètre dans le SelectParameter? Je peux récupérer la liste des colonnes à afficher, et ne remplir mon dataset qu'avec ces colonnes...

    Le pb c'est que je n'arrive pas à lui passer l'objet gridview en lui même. Il m'oblige à lui filer une propriété... J'ai cherché, mais pas trouvé, une propriété qui retourne l'instance de l'objet courant. J'essaye donc de lui passer la propriété Columns. Ca marche un peu, il plante en me disant que DataControlFieldCollection (le type de la propriété Columns) n'est pas serializable.

    Je ne comprend rien
    Pourquoi j'peux pas lui passer mon gridview!! En référence de surcroit!

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

Discussions similaires

  1. [MySQL] Affichage des données d'une base
    Par leloup84 dans le forum PHP & Base de données
    Réponses: 30
    Dernier message: 01/02/2006, 16h35
  2. [Tableaux] Affichage des données par lot
    Par randriarabe dans le forum Langage
    Réponses: 1
    Dernier message: 07/12/2005, 08h23
  3. pb d'affichage des données
    Par new_wave dans le forum XML/XSL et SOAP
    Réponses: 2
    Dernier message: 03/11/2005, 17h31
  4. TDBCtrlGrid - Affichage des données
    Par audreyb dans le forum Bases de données
    Réponses: 1
    Dernier message: 24/10/2004, 13h10
  5. [JTable] Problème d'affichage des données
    Par ddams dans le forum Composants
    Réponses: 2
    Dernier message: 15/09/2004, 17h07

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