我在开发中小型WEB网站或者WEB应用程序通常使用三层架构。有一个比较好的通用的数据访问类往往能大大加快项目的进度,并且如果以后维护,二次开发将相当的方便。

下面是一个通用的访问sql server数据库的访问类。它用到了微软企业开发库的组件Microsoft.Practices.EnterpriseLibrary.Data.dll。这个组件可以从网上下。

下面是详细的代码。我已经加了注释。

using System;
using System.Collections;
using System.Data;
using System.Web;
using System.Configuration;
using System.Data.Common;
using System.Data.SqlClient;
using Microsoft.Practices.EnterpriseLibrary.Data;
using Microsoft.Practices.EnterpriseLibrary.Data.Sql;
using System.Xml;
namespace DAL
{
    #region 实际客户端调用部分
    /// <summary>
    /// 提供通用的数据库访问操作,通过提供相应的存储过程名和参数集,来完成数据的SIUD操作.
    /// </summary>
    public class DataAccess
    {
        /// <summary>
        /// 私有构造函数以阻止客户端的new DataAccess()形式调用
        /// </summary>
        private DataAccess() { }

        #region 查询执行部分
        /// <summary>
        /// 执行查询,返回数据集
        /// </summary>
        /// <param name="connectionName">连接字符串名</param>
        /// <param name="commandType">命令类型(存储过程或T-SQL查询语句)</param>
        /// <param name="command">存储过程名或T-Sql查询语句</param>
        /// <param name="parameters">参数集合(不需要参数则为null)</param>
        /// <returns>数据集</returns>
        public static DataSet ExecuteDataSet(string connectionString, QueryType commandType, string command, SqlParameter[] parameters)
        {
            SqlDatabase database = new SqlDatabase(connectionString);
            SqlCommand sqlCommand = new SqlCommand();
            switch (commandType)
            {
                case QueryType.StorageProcedure:
                    sqlCommand = (SqlCommand)database.GetStoredProcCommand(command);
                    break;
                case QueryType.Text:
                    sqlCommand = (SqlCommand)database.GetSqlStringCommand(command);
                    break;
            }
            AttachParameters(ref sqlCommand, parameters);
            return database.ExecuteDataSet((DbCommand)sqlCommand);

        }

        /// <summary>
        /// 执行查询,返回受影响的行数
        /// </summary>
        /// <param name="connectionName">连接字符串名</param>
        /// <param name="commandType">命令类型(存储过程或T-SQL查询语句)</param>
        /// <param name="command">存储过程名或T-Sql查询语句</param>
        /// <param name="parameters">参数集合(不需要参数则为null)</param>
        /// <returns>受影响的行数</returns>
        public static int ExecuteNonQuery(string connectionString, QueryType commandType, string command, SqlParameter[] parameters)
        {
            SqlDatabase database = new SqlDatabase(connectionString);
            SqlCommand sqlCommand = new SqlCommand();
            switch (commandType)
            {
                case QueryType.StorageProcedure:
                    sqlCommand = (SqlCommand)database.GetStoredProcCommand(command);
                    break;
                case QueryType.Text:
                    sqlCommand = (SqlCommand)database.GetSqlStringCommand(command);
                    break;
            }
            AttachParameters(ref sqlCommand, parameters);
            return database.ExecuteNonQuery((DbCommand)sqlCommand);
        }

        /// <summary>
        /// 执行查询,返回SqlDataReader对象
        /// </summary>
        /// <param name="connectionName">连接字符串名</param>
        /// <param name="commandType">命令类型(存储过程或T-SQL查询语句)</param>
        /// <param name="command">存储过程名或T-Sql查询语句</param>
        /// <param name="parameters">参数集合(不需要参数则为null)</param>
        /// <returns>SqlDataReader对象</returns>
        public static SqlDataReader ExecuteReader(string connectionString, QueryType commandType, string command, SqlParameter[] parameters)
        {
            SqlDatabase database = new SqlDatabase(connectionString);
            SqlCommand sqlCommand = new SqlCommand();
            switch (commandType)
            {
                case QueryType.StorageProcedure:
                    sqlCommand = (SqlCommand)database.GetStoredProcCommand(command);
                    break;
                case QueryType.Text:
                    sqlCommand = (SqlCommand)database.GetSqlStringCommand(command);
                    break;
            }
            AttachParameters(ref sqlCommand, parameters);
            return (SqlDataReader)database.ExecuteReader((DbCommand)sqlCommand);
        }

        /// <summary>
        /// 执行查询,返回结果集中第一行第一列
        /// </summary>
        /// <param name="connectionName">连接字符串名</param>
        /// <param name="commandType">命令类型(存储过程或T-SQL查询语句)</param>
        /// <param name="command">存储过程名或T-Sql查询语句</param>
        /// <param name="parameters">参数集合(不需要参数则为null)</param>
        /// <returns>object对象</returns>
        public static object ExecuteScalar(string connectionString, QueryType commandType, string command, SqlParameter[] parameters)
        {
            SqlDatabase database = new SqlDatabase(connectionString);
            SqlCommand sqlCommand = new SqlCommand();
            switch (commandType)
            {
                case QueryType.StorageProcedure:
                    sqlCommand = (SqlCommand)database.GetStoredProcCommand(command);
                    break;
                case QueryType.Text:
                    sqlCommand = (SqlCommand)database.GetSqlStringCommand(command);
                    break;
            }
            AttachParameters(ref sqlCommand, parameters);
            return database.ExecuteScalar((DbCommand)sqlCommand);
        }

        /// <summary>
        /// 执行查询,返回XmlReader对象
        /// </summary>
        /// <param name="connectionName">连接字符串名</param>
        /// <param name="commandType">命令类型(存储过程或T-SQL查询语句)</param>
        /// <param name="command">存储过程名或T-Sql查询语句</param>
        /// <param name="parameters">参数集合(不需要参数则为null)</param>
        /// <returns>XmlReader对象</returns>
        public static XmlReader ExecuteXmlReader(string connectionString, QueryType commandType, string command, SqlParameter[] parameters)
        {
            SqlDatabase database = new SqlDatabase(connectionString);
            SqlCommand sqlCommand = new SqlCommand();
            switch (commandType)
            {
                case QueryType.StorageProcedure:
                    sqlCommand = (SqlCommand)database.GetStoredProcCommand(command);
                    break;
                case QueryType.Text:
                    sqlCommand = (SqlCommand)database.GetSqlStringCommand(command);
                    break;
            }
            AttachParameters(ref sqlCommand, parameters);
            return database.ExecuteXmlReader((DbCommand)sqlCommand);
        }

        /// <summary>
        /// 将参数关联到查询命令上
        /// </summary>
        /// <param name="sqlCommand">待添加查询参数的SqlCommand对象</param>
        /// <param name="parameters">SqlParameter对象集合</param>
        private static void AttachParameters(ref SqlCommand sqlCommand, SqlParameter[] parameters)
        {
            if (null == parameters)
                return;
            sqlCommand.Parameters.Clear();
            foreach (SqlParameter parameter in parameters)
            {
                sqlCommand.Parameters.Add(parameter);
            }
        }

        #endregion

        #region 获取连接字符串或SqlConnection对象,在新项目中修改连接字符串名称
        /// <summary>
        /// 获取连接字符串,默认节点名 "POConnectionString"
        /// </summary>
        /// <returns></returns>
        public static string GetConnectionString()
        {
            return ConnectionConfiguration.GetConnectionString("POConnectionString");
        }

        /// <summary>
        /// 获取连接字符串,支持 ASP.NET 2.0 程序
        /// </summary>
        /// <param name="nodeName">节点中的name属性的值</param>
        /// <returns>连接字符串</returns>
        private static string GetConnectionString(string NodeName)
        {
            return ConnectionConfiguration.GetConnectionString(NodeName);
        }

        /// <summary>
        /// 获取Sql连接对象,默认节点名 "POConnectionString"
        /// </summary>
        /// <returns></returns>
        public static SqlConnection GetSqlConnectionObject()
        {
            return ConnectionConfiguration.GetSqlConnectionObject("POConnectionString");
        }

        /// <summary>
        /// 获取SqlConnection对象,支持 ASP.NET 2.0程序
        /// </summary>
        /// <param name="nodeName">节点中的name属性的值</param>
        /// <returns>SqlConnection对象</returns>
        private static SqlConnection GetSqlConnectionObject(string NodeName)
        {
            return ConnectionConfiguration.GetSqlConnectionObject(NodeName);
        }

        #endregion

        #region 参数生成器
        /// <summary>
        /// 返回一个具有给定属性的SqlParameter对象
        /// </summary>
        /// <param name="parameterName">参数名</param>
        /// <param name="parameterType">参数Sql类型</param>
        /// <param name="ParameterLength">参数长度</param>
        /// <param name="parameterValue">参数值</param>
        /// <returns>SqlParameter 对象</returns>
        public static SqlParameter ParameterMaker(string parameterName, SqlDbType parameterType, int ParameterLength, object parameterValue)
        {
            return ParameterFactory.Make(parameterName, parameterType, ParameterLength, parameterValue);
        }

        /// <summary>
        /// 返回一个具有给定属性的SqlParameter对象
        /// </summary>
        /// <param name="parameterName">参数名</param>
        /// <param name="parameterValue">参数值</param>
        /// <returns>SqlParameter 对象</returns>
        public static SqlParameter ParameterMaker(string parameterName, object parameterValue)
        {
            return ParameterFactory.Make(parameterName, parameterValue);
        }
        #endregion

    }
    #endregion

    #region QueryType 枚举
    /// <summary>
    /// 查询类型
    /// </summary>
    public enum QueryType
    {
        /// <summary>
        /// 文本查询语句
        /// </summary>
        Text,
        /// <summary>
        /// 存储过程查询
        /// </summary>
        StorageProcedure
    }
    #endregion

    #region 获取连接字符串或SqlConnection连接对象
    /// <summary>
    /// 提供获取连接字符串或连接对象的静态方法
    /// </summary>
    internal class ConnectionConfiguration
    {
        /// <summary>
        /// 私有构造函数用来阻止客户端的new ConnectionConfiguration()调用
        /// </summary>
        private ConnectionConfiguration() { }

        /// <summary>
        /// 获取连接字符串,用于ASP.NET 2.0 程序
        /// </summary>
        /// <param name="nodeName">节点中的name属性的值</param>
        /// <returns>连接字符串</returns>
        public static string GetConnectionString(string nodeName)
        {
            return ConfigurationManager.ConnectionStrings[nodeName].ConnectionString;
        }

        /// <summary>
        /// 获取SqlConnection连接对象,用于ASP.NET 2.0 程序
        /// </summary>
        /// <param name="nodeName">节点中的name属性的值</param>
        /// <returns>SqlConnection对象</returns>
        public static SqlConnection GetSqlConnectionObject(string nodeName)
        {
            return new SqlConnection(GetConnectionString(nodeName));
        }
    }

    #endregion

    #region 参数生成器
    /// <summary>
    /// 参数生成器
    /// </summary>
    internal class ParameterFactory
    {
        /// <summary>
        /// 私有构造函数用来阻止客户端的new ParameterMaker调用
        /// </summary>
        private ParameterFactory() { }

        /// <summary>
        /// 返回一个具有给定属性的SqlParameter对象
        /// </summary>
        /// <param name="parameterName">参数名</param>
        /// <param name="parameterType">参数Sql类型</param>
        /// <param name="ParameterLength">参数长度</param>
        /// <param name="parameterValue">参数值</param>
        /// <returns>SqlParameter 对象</returns>
        public static SqlParameter Make(string parameterName, SqlDbType parameterType, int ParameterLength, object parameterValue)
        {
            SqlParameter parameter = new SqlParameter(parameterName, parameterType, ParameterLength);
            parameter.Value = parameterValue;
            return parameter;
        }

        /// <summary>
        /// 返回一个具有给定属性的SqlParameter对象
        /// </summary>
        /// <param name="parameterName">参数名</param>
        /// <param name="parameterValue">参数值</param>
        /// <returns>SqlParameter 对象</returns>
        public static SqlParameter Make(string parameterName, object parameterValue)
        {
            SqlParameter parameter = new SqlParameter(parameterName, parameterValue);
            return parameter;
        }
    }
    #endregion

}

这么多的代码是不是看起来有点晕。其实使用起来非常方便。我给大家将下使用方法。
1,
2,
3,
4,
大功告成。如何使用那。举几个简单的类子。
下面是一个函数。根据教师ID,学期ID返回教师的教授的课程。
        /// <summary>
        ///根据教师ID,学期ID返回教师的教授的课程
        /// </summary>
        /// <param name="teaid"></param>
        /// <param name="termid"></param>
        /// <returns></returns>
        public static DataTable SelectByTeaidTerm(string teaid, string termid)
        {
            string strSql = "select * from T_Tea_Course where TeaId = @teaid and TermId = @termid";  //构建的查询语句。@teaid,@termid是要传递的参数。
            SqlParameter[] paras =                                  // 构建参数队列
                {
                    DataAccess.ParameterMaker("@teaid",teaid),      //调用DataAccess类的参数构造
                    DataAccess.ParameterMaker("@termid",termid)
                };
            return DataAccess.ExecuteDataSet(DataAccess.GetConnectionString(), QueryType.Text, strSql, paras).Tables[0];     //调用DataAccess类的函数,返回一个datatable对象 其中第一个参数为获取连接字符串,第二个参数为查询命令的类型,QueryType.Text为文本,QueryType.StorageProcedure为存储过程。第三个参数为sql查询文本或者存储过程名称。第四个参数为要传递的参数列表,没有就写null.
        }

这个数据库访问类只能访问sql server数据库。但是前段时间我调到软件实验室开发一个军用保密项目,其中要使用oracle数据库。我想微软企业库肯定有oracledatabase。我试着把数据访问类中SqlParameter,SqlCommand,SqlDatabase...等全替换成OracleParameter,OracleCommand,OracleDataBase...然后调试运行,竟然成功了。大家可以照此把它改成连接oracle,access等数据库的数据访问类。