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 :

Bien formater une classe avec fonction sql


Sujet :

ASP.NET

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Février 2005
    Messages
    63
    Détails du profil
    Informations personnelles :
    Âge : 56
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 63
    Par défaut Bien formater une classe avec fonction sql
    Bonjour tous le monde,

    Je crée un site web sans utiliser les providers de microsoft car je dois importer une grosse base de données avec une structure vraiment trop differente de celle d'asp.net.

    J'en suis donc a la construction de mes classes et je voudrais donc savoir comment bien structurer ma classe et ne pas ecrire comme un bourrin.

    Voici mon code, est'il bien structurer ou est que vous auriez fait autrement?

    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
     
     
    Imports Microsoft.VisualBasic
    Imports System.Data.SqlClient
     
    Public Class Iseekyou_Users
        Private _sqlConnectionString As String
     
     
        Public Sub New()
            _sqlConnectionString = ConfigurationManager.ConnectionStrings("bdd_users").ConnectionString
        End Sub
     
     
        Public Function UserNameExist(ByVal UserName As String) As Integer
            Try
                Dim conn As SqlConnection = Nothing
                Dim cmd As SqlCommand = Nothing
                Dim myreader As SqlDataReader = Nothing
                Dim cpt As Integer = 0
                Try
                    conn = New SqlConnection(_sqlConnectionString)
                    conn.Open()
                    cmd.Connection = conn
                    cmd.CommandText = "SELECT COUNT(*) FROM Users WHERE UserName='" & UserName & "'"
                    myreader = cmd.ExecuteReader
     
                    While myreader.Read
                        cpt = myreader.GetValue(0)
                    End While
     
                    Return cpt
                Finally
                    If Not IsNothing(cmd) Then cmd.Dispose()
                    If Not IsNothing(conn) Then conn.Close() : conn = Nothing
                End Try
     
            Catch ex As Exception
                Throw ex
            End Try
        End Function
     
    End Class
    Par ailleur je n'arrive pas a acceder a la fonction "UserNameExist" car ca me genere une erreur , est ce que je dois mettre cette fonction en shared pour pouvoir y aceder depuis mon formulaire d'inscription?
    Est ce que je dois creer un namespace?

    Merci de partager votre connaissance et expérience avec moi.

  2. #2
    Expert confirmé
    Avatar de Immobilis
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Mars 2004
    Messages
    6 559
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Mars 2004
    Messages : 6 559
    Par défaut
    Salut,
    Citation Envoyé par daviddu54 Voir le message
    Je crée un site web sans utiliser les providers de microsoft car je dois importer une grosse base de données avec une structure vraiment trop differente de celle d'asp.net.
    Provider Microsoft? Grosse base de données différente de ASP.Net?? Ca veut rien dire ça... ASP.Net n'est pas une base de données.

    Sinon, non, c'est pas super bien codé. Ta requête SQL est ouverte aux injections SQL (utiliser des procédures stockées ou du LINQ), inutile de faire un try...catch si c'est juste pour jeter l'erreur. Autant la laisser remonter toute seule. Les objets disposable comme les connections SQL doivent être dans des USING. Exemples ici: http://dotnet.developpez.com/faq/asp...onet_procstock

    A+
    "Winter is coming" (ma nouvelle page d'accueil)

  3. #3
    Expert confirmé

    Avatar de Philippe Vialatte
    Homme Profil pro
    Architecte technique
    Inscrit en
    Juillet 2004
    Messages
    3 029
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Juillet 2004
    Messages : 3 029
    Par défaut
    je dirais même plus, il faudrait lire cet article :

    http://johannblais.developpez.com/tu...acces-donnees/


    Mon Blog

    The Cake is still a lie !!!



    Vous voulez contribuer à la rubrique .NET ? Contactez-moi par MP.
    Vous voulez rédiger des articles pour la rubrique .NET ? Voici la procédure à suivre.

  4. #4
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    Citation Envoyé par Immobilis Voir le message
    Salut,Provider Microsoft? Grosse base de données différente de ASP.Net?? Ca veut rien dire ça... ASP.Net n'est pas une base de données.
    Je pense que daviddu54 fait référence aux Membership Providers qui permettent de gérer les utilisateurs du site, pas aux providers ADO.NET

  5. #5
    Expert confirmé
    Avatar de Immobilis
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Mars 2004
    Messages
    6 559
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Mars 2004
    Messages : 6 559
    Par défaut
    "shared" te permet d'accéder à ta classe sans l'instancier. Ca n'a pas de rapport avec sa visibilité ou portée. Si ça te convient c'est bien. Il n'y a pas d'obligation. Si c'est pour le web par contre il faut faire attention au variables "shared" qui peuvent être partagées par tous les utilisateurs de l'application. Perso, je ne le mettrai pas.

    C'est d'autant plus intéressant de ne pas le faire que ta classe accède à des ressources externe via une connexion SQL. Si tu fais plusieurs appels à "Iseekyou_Users.UserNameExist" tu va créer à chaque fois une instance de connexion. D'un point de vu performances c'est loin d'être acceptable. Tu peux atteindre la limite de connections par défaut du pool. En général cela indique un défaut de conception. Pour éviter cela:
    • Laisse ta classe non "shared"
    • Passe tes objets de connexion et de commande en private accessible dans toute la classe
    • Implémente l'interface IDisposable sur ta classe.

    De plus, si la classe est "shared" toutes les méthodes de la classe doivent l'être aussi.

    Un namespace permet de bien ranger tes classes.
    "Winter is coming" (ma nouvelle page d'accueil)

  6. #6
    Membre confirmé
    Profil pro
    Inscrit en
    Février 2005
    Messages
    63
    Détails du profil
    Informations personnelles :
    Âge : 56
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 63
    Par défaut
    Salut tous le monde,

    tomlev-> Oui exactement ça les providers membershisp,user,profil et role, ne me convienne pas, pour plusieurs raisons:
    * La structure de la base de données que je devrais importées est trop différentes.
    *La base de données "aspnetdb.mdf" crée par les providers .net fait 10 mo vide, or la base de données a importer fait 45 mo et mon futur hebergeur n'autorise que 4 base e 50 mo.
    *Le mot de passe utilisateur de la base de données a importée est au format md5,je n'ai pas reussi a reproduire le meme type de mot de passe avec le fichier "web.config" .

    Donc au final pour pouvoir importer ma base de données j'aurai du surcharger les fonction des 4 classe de gestion des utilisateurs, et si c'est pour faire de la surcharge a tour de bras j'ai autant ecrire mes propre classe.

    Philippe-> Merci ,excellent article ,mais avant d'implementer cette classe generique je trouver réponse à certaines questions.

    Immobilis->
    Laisse ta classe non "shared"
    Passe tes objets de connexion et de commande en private accessible dans toute la classe
    Implémente l'interface IDisposable sur ta classe.
    Tu a mis dans le mille,le but de mon post est justement d'obtenir réponse a ces 3 suggestions.

    Voici a quoi ressemble mon code aprés avoir suivi vos conseils
    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
    Imports System.Data.SqlClient
    Imports System.Data
     
    Public Class Iseekyou_Users
     
        Public Shared Function UserNameExist(ByVal UserName As String) As Integer
            ' Chaîne de connexion
            Dim _sqlConnectionString As String = ConfigurationManager.ConnectionStrings("bdd_users").ConnectionString
            ' Objet connection
            Dim connection As New SqlConnection(_sqlConnectionString)
            ' Ouverture
            connection.Open()
            ' Objet Command
            Dim command As New SqlCommand("SELECT COUNT(UserName) AS cpt FROM Users WHERE UserName=@UserName", connection)
            ' Paramètres
            command.Parameters.Add(New SqlParameter("@UserName", SqlDbType.VarChar, 30))
            command.Parameters("@UserName").Value = UserName
     
            ' Object datareader
            Dim reader As SqlDataReader = command.ExecuteReader()
            Dim cpt As Integer = 0
            While reader.Read()
                cpt = reader.GetValue(0)
            End While
            ' Fermeture reader
            reader.Close()
            ' Fermeture base
            connection.Close()
            Return cpt
        End Function
     
    End Class
    Comment je dois modifier mon code pour implementer les suggestions que tu ma soumises?

  7. #7
    Expert confirmé
    Avatar de Immobilis
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Mars 2004
    Messages
    6 559
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Mars 2004
    Messages : 6 559
    Par défaut
    Citation Envoyé par Immobilis Voir le message
    • Laisse ta classe non "shared"
    • Passe tes objets de connexion et de commande en private accessible dans toute la classe
    • Implémente l'interface IDisposable sur ta classe.
    Les méthodes ne devraient pas être "shared" pour préserver l'instance. Externalise tes objets d'accès aux données en dehors des méthodes pour pouvoir les réutiliser sans créer de nouvelles instances, implémente l'interface IDisposable. Voici un exemple:
    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
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    using System;
    using System.Collections.ObjectModel;
    using System.Configuration;
    using System.Data;
    using System.Data.Common;
     
    namespace DataAccessLayer
    {
        public class SeekUser : IDisposable
        {
            #region Private members
     
            private DbProviderFactory _fcty;
            private IDbCommand _cmd;
            private IDbConnection _cnn;
            private string _connectionString;
            private bool _disposed = false; // Variable to track if Dispose has been called
            private Collection<IDataParameter> _parameters = new Collection<IDataParameter>();
            private string _provider;
            private IDbTransaction _trans;
     
            #endregion
     
            #region Constructor
     
            /// <summary>
            /// 
            /// </summary>
            public SeekUser()
            {
                _fcty = DbProviderFactories.GetFactory(ConfigurationManager.ConnectionStrings[1].ProviderName);
                _cnn = _fcty.CreateConnection();
                _cmd = _fcty.CreateCommand();
     
                _cnn.ConnectionString = _cnn.ConnectionString;
                _cnn.Open();
                _cmd.Connection = _cnn;
                _cmd.CommandTimeout = 60;
            }
     
            #endregion
     
            #region IDisposable
     
            /// <summary>
            /// <c>SeekUser</c> creates members of the following IDisposable types: 
            /// <c>DBFactory</c>. If <c>SeekUser</c> has previously shipped,
            /// adding new members that implement IDisposable to this 
            /// type is considered a breaking change to existing consumers.
            /// </summary>
            public void Dispose()
            {
                // Check if Dispose has already been called 
                if (!_disposed)
                {
                    // Call the overridden Dispose method that contains common cleanup code
                    // Pass true to indicate that it is called from Dispose
                    Dispose(true);
                    // Prevent subsequent finalization of this object. This is not needed 
                    // because managed and unmanaged resources have been explicitly released
                    GC.SuppressFinalize(this);
                }
                _disposed = true;
            }
     
            /// <summary>
            /// Implement a finalizer by using destructor style syntax.
            /// Use of this destructor will be done by GC.
            /// </summary>
            ~SeekUser()
            {
                // Call the overridden Dispose method that contains common cleanup code
                // Pass false to indicate the it is not called from Dispose
                Dispose(false);
            }
     
            /// <summary>
            /// Implement the override Dispose method that will contain common cleanup functionality
            /// </summary>
            /// <param name="disposing">This parameter indicates whether disposition of object is managed by user's coding or GC cleanup.</param>
            private void Dispose(bool disposing)
            {
                if (disposing)
                {
                    try
                    {
                        if (_trans != null)
                        {
                            _trans.Rollback();
                            _trans.Dispose();
                            _trans = null;
                        }
                    }
                    catch { }
                    finally
                    {
                        if (_cmd != null)
                        {
                            _cmd.Dispose();
                            _cmd = null;
                        }
     
                        if (_cnn != null)
                        {
                            _cnn.Dispose();
                            _cnn = null;
                        }
     
                        _fcty = null;
                        _parameters = null;
                        _provider = null;
                        _connectionString = null;
                    }
                }
            }
     
            #endregion
        }
    }
    Assez précis je dois dire...
    A utiliser ainsi:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    using (SeekUser su = new SeekUser())
    {
        su.UserNameExist("toto");
    }
    C'est du C#. A toi de le comprendre et l'adapter.

    A+
    "Winter is coming" (ma nouvelle page d'accueil)

  8. #8
    Membre confirmé
    Profil pro
    Inscrit en
    Février 2005
    Messages
    63
    Détails du profil
    Informations personnelles :
    Âge : 56
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 63
    Par défaut
    Cool exactement ce qu'il me fallait,toutefois une question me vient a l'esprit.

    Est ce que je dois rajouter mes fonctions dans cette classe ou est ce que je peut importer cette classe dans les class que j'ecris?

    pour l'instant j'ai essayer de rajouter ma fonction dans la class que tu ma donner,mais ca ne marche pas, voici le code:
    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
     
     
            Private Function UserNameExist(ByVal UserName As String) As Integer
     
                _cmd.CommandText = "SELECT COUNT(UserName) AS cpt FROM Users WHERE UserName=@UserName"
                _cmd.Parameters.Add(New SqlParameter("@UserName", SqlDbType.VarChar, 30))
                _cmd.Parameters("@UserName").Value = UserName
     
                ' Object datareader
                Dim reader As SqlDataReader = _cmd.ExecuteReader()
                Dim cpt As Integer = 0
                While reader.Read()
                    cpt = reader.GetValue(0)
                End While
                ' Fermeture reader
                reader.Close()
                Dispose()
                Finalize()
     
                Return cpt
            End Function
    Allez immobilis sois pas radin sur les exemples d'implementation ca fait que 2 semaine que je me suis mis a l'asp

Discussions similaires

  1. Réponses: 9
    Dernier message: 08/07/2009, 17h10
  2. [Smarty] Attribuer une class en fonction d'un résultat avec une variable
    Par kitten13 dans le forum Bibliothèques et frameworks
    Réponses: 1
    Dernier message: 25/09/2008, 20h03
  3. Bien programmer une classe avec sa gestion d'erreur
    Par chris81 dans le forum Framework .NET
    Réponses: 8
    Dernier message: 13/02/2007, 18h13
  4. [String] formater une chaine avec un tableau d'argument
    Par jakouz dans le forum Collection et Stream
    Réponses: 6
    Dernier message: 14/04/2006, 15h19
  5. Réponses: 5
    Dernier message: 26/05/2005, 15h40

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