Sqlmanager : facilite l'accès à une base de donnée ms sql

Soyez le premier à donner votre avis sur cette source.

Snippet vu 12 806 fois - Téléchargée 27 fois

Contenu du snippet

Salut tout le monde,
Aujourd'hui, je veux partager avec vous une classe simple et efficace qui vous permet d'executer des requêtes SQL vers un serveur MS SQL.
Cette classe est thread-safe et conçu en Singleton.
Elle permet la gestion des erreurs grâce aux classes QueryResult, SqlQueryResult, SqlNonQueryResult.
Finalement, elle copie les données récupérées dans le DataReader vers une table (DataTable) afin de pouvoir consulter les données en mode déconnecter.

Source / Exemple :


using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Data.SqlClient;
using System.Text;
using System.Runtime.Remoting.Contexts;

namespace zAlbumManager
{
public class SqlManager : IDisposable
{
    //SqlManager est une classe Singleton
    private static SqlManager sqlmanager = new SqlManager();
    private string connectionString = AppSettings.ConnectionString;
    private SqlConnection sqlConnection;
    private bool disposed = false;
    //contient la dernière erreur survenue
    private string lastError;
    public string LastError { get { return lastError; } }

    #region Constructeur
    private SqlManager()
    {
        sqlConnection = new SqlConnection(connectionString);
        OpenConnection();
    }
    public static SqlManager GetInstance()
    {
        return sqlmanager;
    }
    #endregion

    #region ExecuteQuery
    public SqlQueryResult ExecuteQuery(string query, SqlParameter[] parameters)
    {
        lock (this)
        {
            SqlQueryResult sqr = new SqlQueryResult();
            SqlCommand sqlCommand = new SqlCommand(query, sqlConnection);
            if (parameters != null) sqlCommand.Parameters.AddRange(parameters);
            SqlDataReader sqlDataReader = null;
            try
            {
                sqlDataReader = sqlCommand.ExecuteReader();
            }
            catch (Exception e)
            {
                lastError = sqr.ErrorMessage =  e.Message;
                sqr.IsSuccess = false;
                sqr.Error = Error.DataBaseAccessError;
            }
            if (sqr.IsSuccess)
            {
                sqr.Table = new DataReaderAdapter().FillFromReader(sqlDataReader);
                sqlDataReader.Close();
            }
            return sqr;
        }
    }
    public SqlQueryResult ExecuteQuery(string query)
    {
        return this.ExecuteQuery(query, null);
    }
    #endregion
    #region ExecuteNonQuery
    public SqlNonQueryResult ExecuteNonQuery(string query, SqlParameter[] parameters)
    {
        lock (this)
        {
            SqlNonQueryResult snqr = new SqlNonQueryResult();
            SqlCommand sqlCommand = new SqlCommand(query, sqlConnection);
            if (parameters != null) sqlCommand.Parameters.AddRange(parameters);
            try
            {
                //sqlConnection.Open();
                snqr.NumberOfRowsAffected = sqlCommand.ExecuteNonQuery();
            }
            catch (Exception e)
            {
                lastError = snqr.ErrorMessage = e.Message;
                snqr.IsSuccess = false;
                snqr.Error = Error.DataBaseAccessError;
            }
            return snqr;
        }
    }
    public SqlNonQueryResult ExecuteNonQuery(string query)
    {
        return this.ExecuteNonQuery(query, null);
    }
    #endregion

    #region OpenConnection
    public void OpenConnection()
    {
        try
        {
            sqlConnection.Open();
        }
        catch (Exception e)
        {
            lastError = e.Message;
        }
    }
    #endregion
    #region CloseConnection
    public void CloseConnection()
    {
        if (sqlConnection.State != ConnectionState.Closed) sqlConnection.Close();
    }
    #endregion

    #region IDisposable Membres
    public void Dispose()
    {
        if (!this.disposed)
        {
            CloseConnection();
            sqlConnection.Dispose();
            disposed = true;
        }
        GC.SuppressFinalize(this);
        
    }
    #endregion
}
#region QueryResult
public class QueryResult
{
    private bool isSuccess = true;
    private string errorMessage;
    private Error error;
    public Error Error { get { return error; } set { error = value; } }
    public bool IsSuccess { get { return isSuccess; } set { isSuccess = value; } }
    public string ErrorMessage { get { return errorMessage; } set { errorMessage = value; } }

    public override string ToString()
    {
        return " - IsSuccess : " + isSuccess + "\n" + " - Error : " + error + "\n" + " - ErrorMessage : " + errorMessage;
    }
}
#endregion 
#region SqlQueryResult
    public class SqlQueryResult : QueryResult
    {
        private DataTable table;
        public DataTable Table { get { return table; } set { table = value; } }
    }
    #endregion
#region SqlNonQueryResult
public class SqlNonQueryResult : QueryResult
{
    private int numberOfRowsAffected;
    public int NumberOfRowsAffected { get { return numberOfRowsAffected; } set { numberOfRowsAffected = value; } }
}
#endregion

#region DataReaderAdapter
class DataReaderAdapter : DbDataAdapter
{
    public DataTable FillFromReader(IDataReader dataReader)
    {
        DataTable dt = new DataTable();
        this.Fill(dt, dataReader);
        return dt;
    }
}
#endregion
}

Conclusion :


Je suis ouvert à tous conseils pour améliorer cette classe.
Je l'utilise beaucoup et le mieux qu'elle se comporte, meilleur seront mes programmes.

A voir également

Ajouter un commentaire

Commentaires

cs_Alain Proviste
Messages postés
910
Date d'inscription
jeudi 26 juillet 2001
Statut
Modérateur
Dernière intervention
1 février 2015
1 -
je n'ai pas regardé le code mais à lire la description, on se dit "que demande le peuple?"

:)
svaroteaux
Messages postés
4
Date d'inscription
lundi 31 mars 2003
Statut
Membre
Dernière intervention
21 août 2006
-
Il y a une "Application Block" de Microsoft qui répond déjà à cette problématique : Microsoft Application Blocks for .NET

Cette librairie est plutôt bien faite et performante. Elle permet de travailler avec des DataSet ou des SqlReader.
Le package propose une documentation très claire.

Où la trouver : http://www.microsoft.com/downloads/details.aspx?FamilyID=F63D1F0A-9877-4A7B-88EC-0426B48DF275&displaylang=en


Description par Microsoft :
The Microsoft Data Access Application Block for .NET consists of a single .NET-based assembly, which contains all of the functionality necessary to perform the most common data access tasks against a Microsoft SQL Server 2000 database.
Specifically, the Data Access Application Block helps you:
- Call stored procedures or SQL text commands.
- Specify parameter details.
- Return SqlDataReader, DataSet, XmlReader objects, or single values.
- Use strongly typed table and field names.
- Support parameter caching, where required.
- Allow additional tables to be added by passing in pre-existing datasets.
- Update a dataset with user-specified update commands.
- Create SqlCommand objects.
- Allow strongly typed data rows to be passed in place of parameters.
dirthangel
Messages postés
19
Date d'inscription
lundi 5 mai 2003
Statut
Membre
Dernière intervention
19 juin 2007
-
Salut j'ai un problème avec ta class quand j'essaie de la cpompilé j'obtient l'erreur

Error 8 The name 'Error' does not exist in the current context F:\Teddy\Visual Studio 2005\Projects\Mail\SqlClassManager\SqlClassManager.cs 102 34 SqlClassManager

Je débute en C# donc je ne sais pas trop d'ou sa vient , je pense qu'il me manque une référence mais je ne sais pas a quoi :s

merci de votre aide
cs_badrbadr
Messages postés
475
Date d'inscription
jeudi 19 juin 2003
Statut
Membre
Dernière intervention
3 novembre 2008
-
oups, tu peux commenter les deux lignes dans QueryResult comme ça :
//private Error error;
//public Error Error { get { return error; } set { error = value; } }
ou encore juste créer une énumération bidon genre :
public enum Error
{
Unknown
}

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.