#region 构造函数
        /// <summary>
        /// 默认构造函数
        /// </summary>
        public GAdoNet() : this("")
        {
        }        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="strConn">连接字符串</param>
        public GAdoNet(string strConn)
        {
            ConnectionString = strConn;
        }
        #endregion        #region 保护方法
        /// <summary>
        /// 执行 SQL 语句并返回受影响的行数
        /// </summary>
        /// <param name="strSql">SQL 语句</param>
        /// <returns>影响的行数</returns>
        protected int ExecuteNonQuery(string strSql)
        {
            int intRtn = -1;
            objConn = new SqlConnection(ConnectionString);
            objCmd = new SqlCommand(strSql, objConn);            try
            {
                objConn.Open();
                intRtn = objCmd.ExecuteNonQuery();
            }
            catch (System.Data.SqlClient.SqlException e)
            {
                throw e;
            }
            finally
            {
                objCmd.Dispose();
                objConn.Dispose();
            }            return intRtn;
        }        /// <summary>
        /// 执行 SQL 语句并返回受影响的行数
        /// </summary>
        /// <param name="strSql">存储过程名</param>
        /// <param name="objCmdType">命令类型</param>
        /// <param name="objParams">参数集合</param>
        /// <returns>影响的行数</returns>
        protected int ExecuteNonQuery(string strSql, CommandType objCmdType, params SqlParameter[] objParams)
        {
            int intRtn = -1;
            objConn = new SqlConnection(ConnectionString);
            objCmd = new SqlCommand(strSql, objConn);
            objCmd.CommandType = objCmdType;
            for (int i = 0; i < objParams.Length; i++)
            {
                objCmd.Parameters.Add(objParams[i]);
            }            try
            {
                objConn.Open();
                intRtn = objCmd.ExecuteNonQuery();
            }
            catch (System.Data.SqlClient.SqlException e)
            {
                throw e;
            }
            finally
            {
                objCmd.Dispose();
                objConn.Dispose();
            }            return intRtn;
        }        /// <summary>
        /// 执行查询,并返回查询所返回的结果集中第一行的第一列。
        /// </summary>
        /// <param name="strSql">SQL 语句</param>
        /// <returns>第一行的第一列的值</returns>
        protected object ExecuteScalar(string strSql)
        {
            object objRtn = null;
            objConn = new SqlConnection(ConnectionString);
            objCmd = new SqlCommand(strSql, objConn);            try
            {
                objConn.Open();
                objRtn = objCmd.ExecuteScalar();
            }
            catch (System.Data.SqlClient.SqlException e)
            {
                throw e;
            }
            finally
            {
                objCmd.Dispose();
                objConn.Dispose();
            }            return objRtn;
        }        /// <summary>
        /// 执行查询,并返回查询所返回的结果集中第一行的第一列。
        /// </summary>
        /// <param name="strSql">存储过程名</param>
        /// <param name="objCmdType">命令类型</param>
        /// <param name="objParams">参数集合</param>
        /// <returns>第一行的第一列的值</returns>
        protected object ExecuteScalar(string strSql, CommandType objCmdType, params SqlParameter[] objParams)
        {
            object objRtn = null;
            objConn = new SqlConnection(ConnectionString);
            objCmd = new SqlCommand(strSql, objConn);
            objCmd.CommandType = objCmdType;
            for (int i = 0; i < objParams.Length; i++)
            {
                objCmd.Parameters.Add(objParams[i]);
            }            try
            {
                objConn.Open();
                objRtn = objCmd.ExecuteScalar();
            }
            catch (System.Data.SqlClient.SqlException e)
            {
                throw e;
            }
            finally
            {
                objCmd.Dispose();
                objConn.Dispose();
            }            return objRtn;
        }        /// <summary>
        /// 返回 DataReader 对象
        /// </summary>
        /// <param name="strSql">SQL 语句</param>
        /// <returns>DataReader 对象</returns>
        protected SqlDataReader ExecuteReader(string strSql)
        {
            objConn = new SqlConnection(ConnectionString);
            objCmd = new SqlCommand(strSql, objConn);
            SqlDataReader objReader = null;            try
            {
                objConn.Open();
                objReader = objCmd.ExecuteReader(CommandBehavior.CloseConnection);
            }
            catch (System.Data.SqlClient.SqlException e)
            {
                throw e;
            }            return objReader;
        }        /// <summary>
        /// 返回 DataReader 对象
        /// </summary>
        /// <param name="strSql">存储过程名</param>
        /// <param name="objCmdType">命令类型</param>
        /// <param name="objParams">参数集合</param>
        /// <returns>SqlDataReader</returns>
        protected SqlDataReader ExecuteReader(string strSql, CommandType objCmdType, params SqlParameter[] objParams)
        {
            objConn = new SqlConnection(ConnectionString);
            objCmd = new SqlCommand(strSql, objConn);
            objCmd.CommandType = objCmdType;
            for (int i = 0; i < objParams.Length; i++)
            {
                objCmd.Parameters.Add(objParams[i]);
            }            SqlDataReader objReader = null;            try
            {
                objConn.Open();
                objReader = objCmd.ExecuteReader(CommandBehavior.CloseConnection);
            }
            catch (System.Data.SqlClient.SqlException e)
            {
                throw e;
            }            return objReader;
        }

解决方案 »

  1.   


            /// <summary>
            /// 返回DataSet
            /// </summary>
            /// <param name="strSql">存储过程名</param>
            /// <param name="strTableName">表名</param>
            /// <param name="objCmdType">命令类型</param>
            /// <param name="objParams">参数集合</param>
            /// <returns>DataSet</returns>
            protected DataSet ExecuteDataSet(string strSql, string strTableName,
                CommandType objCmdType, params SqlParameter[] objParams)
            {
                objConn = new SqlConnection(ConnectionString);
                objCmd = new SqlCommand(strSql, objConn);
                objCmd.CommandType = objCmdType;
                for (int i = 0; i < objParams.Length; i++)
                {
                    objCmd.Parameters.Add(objParams[i]);
                }
                objAdapter = new SqlDataAdapter(objCmd);            DataSet objDataSet = null;            try
                {
                    objConn.Open();
                    objDataSet = FillDataSet(objAdapter, strTableName);
                }
                catch (System.Data.SqlClient.SqlException e)
                {
                    throw e;
                }
                finally
                {
                    objAdapter.Dispose();
                    objCmd.Dispose();
                    objConn.Dispose();
                }            return objDataSet;
            }        /// <summary>
            /// 返回DataSet
            /// </summary>
            /// <param name="strSql">SQL语句</param>
            /// <param name="strTableName">表名</param>
            /// <returns>DataSet</returns>
            protected DataSet ExecuteDataSet(string strSql, string strTableName)
            {
                objConn = new SqlConnection(ConnectionString);
                objAdapter = new SqlDataAdapter(strSql, objConn);            DataSet objDataSet = null;            try
                {
                    objConn.Open();
                    objDataSet = FillDataSet(objAdapter, strTableName);
                }
                catch (System.Data.SqlClient.SqlException e)
                {
                    throw e;
                }
                finally
                {
                    objAdapter.Dispose();
                    objConn.Dispose();
                }            return objDataSet;
            }
            #endregion        #region 私有方法
            /// <summary>
            /// 填充数据集
            /// </summary>
            /// <param name="objAdapter">SqlDataAdapter</param>
            /// <param name="strTableName">表名</param>
            /// <returns>DataSet</returns>
            private DataSet FillDataSet(SqlDataAdapter objAdapter, string strTableName)
            {
                DataSet objDataSet = new DataSet();            try
                {
                    objAdapter.Fill(objDataSet, strTableName);                // 记录数
                    _intRecordCount = objDataSet.Tables[strTableName].Rows.Count;
                    // 页数
                    _intPageCount = 0;
                    // 页号
                    _intFirstPage = 0;
                    _intPreviousPage = 0;
                    _intNextPage = 0;
                    _intLastPage = 0;                // 分页填充数据
                    if (_intRecordCount > 0 && _intPageSize > 0)
                    {
                        // 页数
                        _intPageCount = (int) Math.Ceiling(_intRecordCount * 1.0 / _intPageSize);
                        // 页号
                        _intFirstPage = 1;
                        _intPreviousPage = _intPageNo - 1;
                        _intNextPage = _intPageNo + 1;
                        _intLastPage = _intPageCount;
                        // 规范页号
                        _intPageNo = (_intPageNo > _intPageCount) ? _intPageCount : _intPageNo;
                        _intPreviousPage = (_intPreviousPage <= 0) ? 1 : _intPreviousPage;
                        _intNextPage = (_intNextPage > _intPageCount) ? _intPageCount : _intNextPage;                    objDataSet.Clear();
                        // 分页填充
                        objAdapter.Fill(objDataSet, (_intPageNo - 1) * _intPageSize, _intPageSize, strTableName);
                    }
                }
                catch (System.Data.SqlClient.SqlException e)
                {
                    throw e;
                }            return objDataSet;
            }
            #endregion
        }
    }
      

  2.   

    这是一个只针对sqlserver的数据库操作基类,使用时,先派生一个类,然后再进行相关操作。请各位给些意见。
      

  3.   

    1、建议用webservice实现,这样部署方便
    2、选择数据库连接方式"OLEDBORA";"ORACLIENT";"SQLCLIENT";
    3、写几个常用函数
      CreateConnection( )
      private int ExecSQL(string[] SQL)
      private DataSet InitDataSetTableBySQL( string astrTableName,string astrSQL)
      public int GetReturnIntBySQL(string astrSQL) 
      public double GetReturnDoubleBySQL(string astrSQL) 
      public string GetReturnStringBySQL(string astrSQL) 
      

  4.   

    建议:
    1.提供多种查询方式,不使用直接传递SQL语句。
    2.存储过程可以单独作类封装,最好不混在这里
    3.提供更新,删除的操作(最好制作生成SQL语句的类工长)
    4.使操作可以应用到外部的Transcation操作中
    另外,最好能把次类的功能缩小到只处理单表。这样就可以得到表的字段和类型,对于
    构造SQL语句将有很大的帮助。
      

  5.   

    Microsoft.ApplicationBlocks.Data
    看一下这个吧:)
      

  6.   

    to: arding123(阿拉丁) 我没有接触过web service,没有想过用这种方法来实现。有霎时间我看看,实现一份再拿来请大家提些意见。
    to: 513(513) 实际上,这是我从自己的ado封装类修改而成的一个新类,只是将底的实现,根据ado.net重新实现了一份,没有太多考虑其它的因素。对你提出的问题,有些地方我还不知道如果实现更好,还请多多指教。事实上,对存储过程的支持,也可以用来模仿构造sql,如insert into temo (id, name) valeus (@intId, @strName),使用这样的语句,再使用存储过程调用的方法,即可以构造sql了。,如果有更复杂的sql,还是要自己手写了。我是做web开发的,对asp/php比较熟,对asp/php中的mvc模式开发比较熟。用net是个人兴趣,也是因为工作需要。刚刚接触一个月左右的时间,很多东西还不熟悉,只要有时间,我会多来.net版转转的。
    to: henryfan1(每天好心情(*_*)) 从网上找了些相关的资料,感觉很好,正准备down源码来看看。谢谢
      

  7.   

    一个用 vb.net 写的连接存储过程, 不较楼主写得这么规范. 希望楼主帮我改改Public Function CommRS(ByVal ProcedureName As String, ByVal myParamArray() As SqlParameter) As DataTable
      Dim objConn = new SqlConnection(ConnectionString);
      Dim myCommand As New SqlCommand(ProcedureName, objConn)
      
      Dim i As Integer
      Dim DS As New DataSet()  myCommand.CommandType = CommandType.StoredProcedure
      For i = 0 To myParamArray.Length - 1
          myCommand.Parameters.Add(myParamArray(i))
      Next
      Try
        Dim SDA As New SqlDataAdapter(myCommand)
        SDA.Fill(DS, "myTable")    SDA.Dispose()
        SDA = Nothing
      Catch (ex As System.Data.SqlClient.SqlException)
        throw e;
      Finally
        myCommand.Dispose()
        Set myCommand = Nothing
        objConn.Dispose()
        Set objConn = Nothing
      End Try
      
      Return DS.Tables("myTable")
    End Function
      

  8.   

    to: yinson(田海人)我看了你的代码,我们实现的功能相似,代码也差不多,我没有其它的建议。
    从你的代码看,CommRS是类中的一个方法。找到一处错误:
      Catch (ex As System.Data.SqlClient.SqlException)
        throw e;
    应为
      Catch (ex As System.Data.SqlClient.SqlException)
        Throw ex
    吧?!
    用.net一直在使用C#,对VB.Net的语法不熟,你自己再看看这样修改是否合适。
    我觉得,无论使用C#,还是VB.Net,主要是学习.Net FrameWork,这样才能写出更好的程序。还有,面向对象的思想,及许多其它的知识是必不可少的。
    扯远了,这样的论述太多,还是让别人来说明吧。
      

  9.   

    SqlDataReader ExecuteReader
     
    只能在连接打开是操作!不只到你怎么处理??
      

  10.   

    to: wwonion(洋葱)我的代码中有这样一行objReader = objCmd.ExecuteReader(CommandBehavior.CloseConnection)只要用户使用SqlDataReader后,调用Close()方法关闭就行了。
      

  11.   

    这是MSDN中的帮助
    [C#]
    public SqlDataReader ExecuteReader(
       CommandBehavior behavior
    );
    CommandBehavior.CloseConnection 
    受 .NET Framework 精简版的支持。
     在执行该命令时,如果关闭关联的 DataReader 对象,则关联的 Connection 对象也将关闭。
      

  12.   

    呵呵,我觉得翻页的函数不应该写在这里,
    这个做一个基础类,保留返回dataset等等的单纯执行sql语句的东东就行了
      

  13.   

    to:  redfoxhuang(C++++) 分页是网站程序必不可少的一个组成部分,在这个里面实现的还不好,只是针对dataset做了而已,我准备做一个更通用的。我对比了使用存储过程等实现的方法,可是,目前已经实现的分页程序,都是针对个别程序的地,没有一个能用的。(除了使用Adapter.Fill()方法)
    想听听你的意见,你觉得,分页不必要加,还是要加到另一外类中?或者,写到页面中(我觉得在页面中写不大好,虽然,datagrid具备了分页的功能)。
      

  14.   

    刚才打错了一个字,就是:我对比了使用存储过程等实现的方法,可是,目前已经实现的分页程序,都是针对个别程序的地,没有一个通用的。(除了使用Adapter.Fill()方法)
      

  15.   

    /// <summary>
    /// 删除记录
    /// </summary>
    /// <param name="intId">记录id</param>
    /// <returns>影响的行数</returns>
    public int Delete(int intId)
    {
        int intAffectRows = -1;    strSql = "sp_SubjectDel";    SqlParameter objId = new SqlParameter("@intId", intId);
        SqlParameter objAffectRows = new SqlParameter();    // Id
        objId.Direction = ParameterDirection.Input;
        objId.DbType = DbType.Int32;    // AffectRows
        objAffectRows.Direction = ParameterDirection.Output;
        objAffectRows.ParameterName = "@intAffectRows";
        objAffectRows.DbType = DbType.Int32;    try
        {
            ExecuteNonQuery(strSql, CommandType.StoredProcedure,
                objId ,objAffectRows);        intAffectRows = Convert.ToInt32(objAffectRows.Value);
        }
        catch(System.Data.SqlClient.SqlException e)
        {
            throw e;
        }    return intAffectRows;
    }
    这是我的数据库操作类的一个方法,用来删除记录。调用的存储过程,一个输入参数,一个输出参数。为了完成一个网站后台,我才写的这个类,可以说,还是有一定的实用性的。发到这儿来,想听听大家的意见,把他写的更好。
      

  16.   

    我现在就是不知道怎么去考虑写这个数据库的东西,不知道要怎么样去设计这个访问类,就是说你写的一些处理存储过程和sql语句的目的是看着什么,我现在在程序里也是急需要用到存储过程,而且我已经在sql里写好了这个存储过程,可是我就是不会在程序调用存储过程,其实关键的关键是我不知道该怎么样去数据库通类里去加上这样的一个处理存储过程的方法,有这方面的参考资料可以指点一下吗?
      

  17.   

    楼主,我也写了一个数据库访问的基类,和你的有写不同 我把有些(不是全部的)变量,方法定义成static 的  比如增删改的操作 。
      

  18.   

    ..........,,::..............................................................................................................................
    ........,,BB@@............++@@@@33..............33..................................................,,++....................,,33,,..........
    ........@@MM99......::99AA99@@@@99..............@@AAAA@@............................................++MMAA....................AABB::,,,,....
    ........,,AA::,,99@@99::33++..............,,3399MMAA++........................................,,++....AABB::33,,............::AAMMBB@@MMAA..
    ........++@@,,..++,,....33BB................++BBAA........................::99AA::............,,AA..,,MMMMMMMM99........33BBMMAA::,,99MMBB,,
    ......++AABB,,....++++..33AA................,,@@::33..................::BBMMMM99..............::MM..99MMMMMM99........33MMAA++..++@@99++,,..
    ......99::MM33::@@AABB,,++AA................AA::,,AA++@@................,,,,@@BB..............99AA..@@AA33BB::......,,MM@@..::AAMM@@........
    ....,,@@..339933@@++33..::BB..............33AA33@@MM@@BB....................BBMM++9999......,,BBAA..,,..33MMMMAA....,,MM33..33MMBB::AA++....
    ....,,@@......,,........++BB............,,BB,,33AABB@@,,..........,,,,,,::@@MMMMMMBB++......@@AA@@99....AABBAA99......++,,..,,MMMM++++++....
    ....++BB++..............++MM..........,,BB33....9999..............33BBMMMMMM99,,,,..........++,,AA@@....AA99AA::............,,MMMM@@........
    ....33MM33..............::MM,,........::99......AA::,,++............,,::++....................,,MM99....BB99@@33............33MMMMAA........
    ....33MM,,..............,,BB,,..................,,....@@99......................................99,,....BB99................++MMBBBBAA......
    ....::BB................++MM,,..........................BB++............................................AA99................@@MMBB@@99......
    ......,,..............,,AA99............................++::............................................::::..................::,,..........
      

  19.   

    运用接口Microsoft.ApplicationBlocks.Data的基础上封装了一下。
    http://www.aspxcn.com/dotnetbbs/View.aspx?fbId=17&Id=223661
      

  20.   

    to: JohnnyDJ(人不来车不往)
    指点不敢妆,共同讨论吧。
    在我的类中共提供了经过重载的4个方法,一个是针对sql的,另外一个是针对存储过程的(也可以针对特殊的sql,在前面我已经举过例子了)。
    我不明白你指的不会调用存储过程是什么意思?是在ado.net中不会调用,还是不清楚存储过程执行后,会得到什么样的结果。
    我个人的感觉:调用存储过程主要是两方面,存储过程名和参数(in/out),只要你提供的方法可以实现多参数就可以了,而且,要让out类型的参数可以返回值。为了解决多参数的问题,我使用了C#中的params参数类型,就这样,我就是这样想的。
    不知我是否说明了,我们可以继续讨论。
    to: stpangpang(胖在一方)我写这个类,主要是为了实现一个公共的数据库操作,当时没有想太多。前面我已经说过了,最初是用asp+ado写的一个数据库操作类,使用.net后,又使用ado.net重写的类,当然,结构和方法都不同了,只保留了一些最初的想法。
    我写的是一个抽象类,不能被实例化,要派生一个类后才能使用,这主要是基于我自己写程序的习惯考虑。主要是为了多个类使用相同的数据库连接,这样,就不必写重复的连接代码了。
    我的开发结构是首先派生出一个子类,用来实现数据库连接。然后,再派生出子类的子类,基本上是一个表一个类。
    静态方法我没有考虑过,在后面的修改中我会考虑加入的。
    至于你提到的增删改操作,我实在不知道怎样才能写出一个通用的方法来,所以,只在ado.net基础之上提供了四个方法。我也看过一些网友写的增删改的方法,觉得并不是能用的方法,不知你是如何实现的?
    我刚使用.net一个月左右的时间,刚刚起步,将代码发到这儿,就是想和大家交流一下,这样才能提高。
    to: ddangerous169(零点烛光)我捕捉的异常也没有进行处理,只是又抛出而已。
    在异常处理方法,我不大熟,只是习惯性的加上了try/catch/finally。还请有这方面经验的朋友指点。
    to: cqnetboy(NetBoy) 1、这主要是基于个人习惯考虑的,不想这个类被实例化,只有派生出一个类后,才能进行相关的操作。这样,可以在这个类的基础上,构建出一个复杂的类图(这只是一个想法而已)。
    2、我刚刚完成了一个网站的后台程序,下面就是我的举例代码。
      

  21.   

    这是一个数据库连接的类,派生自GAdoNet
    using System;
    using System.Configuration;
    using System.Data;
    using System.Data.SqlClient;
    using System.Data.SqlTypes;using Gcs.Data;
    using Gcs.String;namespace Hospital.Database
    {
        /// <summary>
        /// 数据库连接
        /// </summary>
        public abstract class Hospital : GAdoNet
        {
            public Hospital() :
                base(ConfigurationSettings.AppSettings["strConnection"])
            {
            }
        }
    }这针对一个表的封装类,派生自Hospital
    using System;
    using System.Data;
    using System.Data.SqlClient;
    using System.Data.SqlTypes;using Gcs.Data;
    using Gcs.String;namespace Hospital.Database
    {
        /// <summary>
        /// 友情链接
        /// </summary>
        public class FriendLink : Hospital
        {
            private int m_intId;
            private string m_strName;
            private string m_strUrl;
            private string m_strFileName;
            private int m_intHeight;
            private int m_intWidth;        #region 公有属性, 对应表中字段
            /// <summary>
            /// ID
            /// </summary>
            public int ID
            {
                get
                {
                    return m_intId;
                }
            }        /// <summary>
            /// 友情链接名称
            /// </summary>
            public string Name
            {
                get
                {
                    return m_strName;
                }
                set
                {
                    m_strName = value;
                }
            }        /// <summary>
            /// 友情链接地址
            /// </summary>
            public string Url
            {
                get
                {
                    return m_strUrl;
                }
                set
                {
                    m_strUrl = value;
                }
            }        /// <summary>
            /// 友情链接图片名称
            /// </summary>
            public string FileName
            {
                get
                {
                    return m_strFileName;
                }
                set
                {
                    m_strFileName = value;
                }
            }        /// <summary>
            /// 友情链接图片高度
            /// </summary>
            public int Height
            {
                get
                {
                    return m_intHeight;
                }
                set
                {
                    m_intHeight = value;
                }
            }        /// <summary>
            /// 友情链接图片宽度
            /// </summary>
            public int Width
            {
                get
                {
                    return m_intWidth;
                }
                set
                {
                    m_intWidth = value;
                }
            }
            #endregion        public FriendLink() : base()
            {
            }        /// <summary>
            /// 添加记录
            /// </summary>
            /// <returns>新标识</returns>
            public int AddNew()
            {
                int intNewId = -1;            strSql = "INSERT INTO FriendLink"
                    + " (Name, Url, FileName, Height, Width) VALUES"
                    + " (@strName, @strUrl, @strFileName, @intHeight, @intWidth)"
                    + " SELECT @@IDENTITY";            SqlParameter objName = new SqlParameter("@strName", Name);
                SqlParameter objUrl = new SqlParameter("@strUrl", Url);
                SqlParameter objFileName = new SqlParameter("@strFileName", FileName);
                SqlParameter objHeight = new SqlParameter("@intHeight", Height);
                SqlParameter objWidth = new SqlParameter("@intWidth", Width);            // Name
                objName.Direction = ParameterDirection.Input;
                objName.DbType = DbType.String;            // Url
                objUrl.Direction = ParameterDirection.Input;
                objUrl.DbType = DbType.String;            // FileName
                objFileName.Direction = ParameterDirection.Input;
                objFileName.DbType = DbType.String;            // Height
                objHeight.Direction = ParameterDirection.Input;
                objHeight.DbType = DbType.Int32;            // Width
                objWidth.Direction = ParameterDirection.Input;
                objWidth.DbType = DbType.Int32;            try
                {
                    object objId = ExecuteScalar(strSql, CommandType.Text,
                        objName, objUrl, objFileName, objHeight, objWidth);                intNewId = (objId == null) ? -1 : Convert.ToInt32(objId);
                }
                catch (System.Data.SqlClient.SqlException e)
                {
                    throw e;
                }            return intNewId;
            }        /// <summary>
            /// 删除记录
            /// </summary>
            /// <param name="id">标识</param>
            /// <returns>影响的行数</returns>
            public int Delete(int id)
            {
                int intRtn = -1;
                strSql = "DELETE FriendLink WHERE id=" + id;            try
                {
                    intRtn = ExecuteNonQuery(strSql);
                }
                catch (System.Data.SqlClient.SqlException e)
                {
                    throw e;
                }            return intRtn;
            }        /// <summary>
            /// 记录列表
            /// 使用后, 请关闭 SqlDataReader
            /// </summary>
            /// <returns>SqlDataReader</returns>
            public SqlDataReader Browse()
            {
                SqlDataReader objReader = null;
                strSql = "SELECT * FROM FriendLink ORDER BY id";            try
                {
                    objReader = ExecuteReader(strSql);
                }
                catch (System.Data.SqlClient.SqlException e)
                {
                    throw e;
                }            return objReader;
            }        /// <summary>
            /// 查看记录信息
            /// </summary>
            /// <param name="intId">记录id</param>
            /// <returns>true or false</returns>
            public bool View(int intId)
            {
                bool blnRtn = false;
                strSql = "SELECT * FROM FriendLink WHERE id = " + intId;            try
                {
                    SqlDataReader objReader = ExecuteReader(strSql);                if (objReader.Read())
                    {
                        blnRtn = true;                    m_intId = intId;
                        Name = objReader.GetString(objReader.GetOrdinal("Name"));
                        Url = objReader.GetString(objReader.GetOrdinal("Url"));
                        FileName = objReader.GetString(objReader.GetOrdinal("FileName"));
                        Height = objReader.GetInt32(objReader.GetOrdinal("Height"));
                        Width = objReader.GetInt32(objReader.GetOrdinal("Width"));
                    }                objReader.Close();
                }
                catch (System.Data.SqlClient.SqlException e)
                {
                    throw e;
                }            return blnRtn;
            }    }
    }由于篇幅的限制,我只挑选了几个方法,希望能说明我的数据库操作类的使用。
    感谢大家关注我的帖子,请大家继续提意见!
      

  22.   

    呵呵,意思理解错误了,昨天晚上先down 下来帖子,没有仔细研究你的代码 !汗
    今天再看看,我感觉我们的意思差不多~  我写的增删改就是你的重载的ExecuteNonQuery方法不过是静态的,
    我有一个建议,在执行一些方法(传入sql语句)之前,先剔除一些非法字符~
      

  23.   

    to: stpangpang(胖在一方)我还真没有考虑到要替换特殊字符的事情。
    目前这个类只是自己使用,一些问题都在派生类中注意了,谢谢你的建议!
      

  24.   

    stpangpang(胖在一方)1;增加一个 hasData(string strSql) 函数,一般有些情况如注册,增加数据等,得判断有没有重复的值,如果有的话 ... 没有的话...
                    }
    2 : 建议写一个带有事物的方法  参数是一个 strsql 数组
         因为现在的一些操作,要同时网好几个表中写数据,如果光用  int ExecuteNonQuery(string strSql) 方法的话,不好实现数据回滚,得自己写事物。
    这个正在考虑,测试,等完成了,请你指正一下3;看了你的执行存储过程的一些方法 
      我的想法是,既然是存储过程,就直接设定cmd.CommandType, 减少出错的几率4;如果客户端经常的访问数据库,这样写,服务器的开销大吗?建立连接开销比较大,我的想法是连接设置成static,或者使用缓冲池?to: stpangpang(胖在一方)1、一般情况下,我都是使用ExecuteScalar来完成类似的功能,sql可以这样写select count(*) from TableName where condition,ExecuteScalar返回的是表第一行第一列的值。2、我的程序中很少用到事务,而且,多半都是在存储过程中使用事务。所以,没有考虑到这方面的问题,先看看你的实现,向你学习。3、你看一下我前面的帖子,其实,执行存储过程的语句,还可以用来执行特殊的sql,如:insert into temo (id, name) valeus (@intId, @strName)。最初我只是用来执行存储过程,后来又改成现在的方式的,因为我觉得这样更方便。我在考虑,是否再添加一个重载的方法,专用执行存储过程,这样就更方便了。4、我看ado.net中提到,连接池可以由ConnectionString的设置实现,只是我在web的实现上还没有感觉到有什么好处。我正想问这方面的问题呢。
    我的这段代码,还不完善,并没有发挥ado.net的优点,比如对dataset的使用等。我正学习,随着学习的深入,我会不断的修改代码,而且,经过修改的代码,都会在公司的项目中使用的。
      

  25.   

    网友提到我的FillDataSet中实现了分页功能,针对这段代码,下面是我的分页程序。这个例子是我随手写的,以上面帖出的FriendLink为例子。FriendLink objFriend = new FriendLink();objFriend.PageSize = 20;
    objFriend.PageNo = 1;
    objFriend.Browse();这样产生的DataSet就是经过分页的数据了。objFriend.PageNo是页号,PageSize是页大小。这个方面还存在一些问题,当用户选择分页时(PageSize > 0),我Fill了两次DataSet,这肯定会影响速度。而且,我还想对SqlDataReader进行分页,由于这次公司的项目不用对SqlDataReader进行分页,而且,我还没有找到更好的办法,所以没有实现。
    前面也有网友提到了,是否有必要进行分页的问题。在这个问题方面,我比较倾向于完成类似的代码。欢迎各位继续发表意见,如果能更好的解决方案最好。谢谢各位关注。
      

  26.   

    一个自定义分页的存储过程
    CREATE PROCEDURE sp_GetEmployeesByPage
    @PageNumber int,
    @PageSize int
    ASCREATE TABLE #Temp
    (
    ID  int IDENTITY PRIMARY KEY,
    EmployeeID int,
    LastName nvarchar(20),
    FirstName nvarchar(10),
    Title nvarchar(30),
    TitleOfCourtesy nvarchar(25),
    Address nvarchar(60),
    City nvarchar(15),
    Region nvarchar(15),
    Country nvarchar(15),
    Notes ntext
    )INSERT INTO #Temp
    (
    EmployeeID,
    LastName,
    FirstName,
    Title,
    TitleOfCourtesy,
    Address,
    City,
    Region,
    Country,
    Notes
    )
    SELECT 
    EmployeeID,
    LastName,
    FirstName,
    Title,
    TitleOfCourtesy,
    Address,
    City,
    Region,
    Country,
    Notes
    FROM 
      Employees ORDER BY EmployeeID ASCDECLARE @FromID int
    DECLARE @ToID intSET @FromID = ((@PageNumber - 1) * @PageSize) + 1
    SET @ToID = @PageNumber * @PageSize-- select the page of records
    SELECT * FROM #Temp WHERE ID >= @FromID AND ID <= @ToID
    GO-------调用
    SqlCommand cmd = new SqlCommand("sp_GetEmployeesByPage", conn);
        cmd.CommandType = CommandType.StoredProcedure;
        cmd.Parameters.Add(new SqlParameter("@PageNumber", SqlDbType.Int, 4));
        cmd.Parameters["@PageNumber"].Value = Datagrid1.CurrentPageIndex + 1;
        cmd.Parameters.Add(new SqlParameter("@PageSize", SqlDbType.Int, 4));
        cmd.Parameters["@PageSize"].Value = Datagrid1.PageSize;
        
        // open the connection and get the Reader
        conn.Open();
        SqlDataReader reader = cmd.ExecuteReader();
               
        // bind the reader to the DataList
        Datagrid1.DataSource = reader;
        Datagrid1.DataBind();
      

  27.   

    其实我原来 对插入数据有一个想法(针对没有重复数据的数据)
    用 if exists(select * from  table where condition) insert into ....else ....
    写一个存储过程,有返回值的,但是水平不够,没有研究. 有时间讨论一下
      

  28.   

    我觉的这样我就满足了 :) (PetShop.Net DEMO中的例子) using System;
    using System.Configuration;
    using System.Data;
    using System.Data.SqlClient;
    using System.Collections;namespace PetShop.Components {
    public abstract class Database {
    public static readonly string CONN_STRING = ConfigurationSettings.AppSettings["ConnString"];

    private static Hashtable parmCache = Hashtable.Synchronized(new Hashtable()); public static int ExecuteNonQuery(string connString, CommandType cmdType, string cmdText, params SqlParameter[] cmdParms) {
    SqlCommand cmd = new SqlCommand(); using (SqlConnection conn = new SqlConnection(connString)) {
    PrepareCommand(cmd, conn, null, cmdType, cmdText, cmdParms);
    int val = cmd.ExecuteNonQuery();
    cmd.Parameters.Clear();
    return val;
    }
    } public static int ExecuteNonQuery(SqlTransaction trans, CommandType cmdType, string cmdText, params SqlParameter[] cmdParms) {
    SqlCommand cmd = new SqlCommand();
    PrepareCommand(cmd, trans.Connection, trans, cmdType, cmdText, cmdParms);
    int val = cmd.ExecuteNonQuery();
    cmd.Parameters.Clear();
    return val;
    } public static SqlDataReader ExecuteReader(string connString, CommandType cmdType, string cmdText, params SqlParameter[] cmdParms) {
    SqlCommand cmd = new SqlCommand();
    SqlConnection conn = new SqlConnection(connString); try {
    PrepareCommand(cmd, conn, null, cmdType, cmdText, cmdParms);
    SqlDataReader rdr = cmd.ExecuteReader(CommandBehavior.CloseConnection);
    cmd.Parameters.Clear();
    return rdr;
    }
    catch {
    conn.Close();
    throw;
    }
    }

    public static object ExecuteScalar(string connString, CommandType cmdType, string cmdText, params SqlParameter[] cmdParms) {
    SqlCommand cmd = new SqlCommand(); using (SqlConnection conn = new SqlConnection(connString)) {
    PrepareCommand(cmd, conn, null, cmdType, cmdText, cmdParms);
    object val = cmd.ExecuteScalar();
    cmd.Parameters.Clear();
    return val;
    }
    } public static void CacheParameters(string cacheKey, params SqlParameter[] cmdParms) {
    parmCache[cacheKey] = cmdParms;
    } public static SqlParameter[] GetCachedParameters(string cacheKey) {
    SqlParameter[] cachedParms = (SqlParameter[])parmCache[cacheKey];

    if (cachedParms == null)
    return null;

    SqlParameter[] clonedParms = new SqlParameter[cachedParms.Length]; for (int i = 0, j = cachedParms.Length; i < j; i++)
    clonedParms[i] = (SqlParameter)((ICloneable)cachedParms[i]).Clone(); return clonedParms;
    } private static void PrepareCommand(SqlCommand cmd, SqlConnection conn, SqlTransaction trans, CommandType cmdType, string cmdText, SqlParameter[] cmdParms) {
    if (conn.State != ConnectionState.Open)
    conn.Open(); cmd.Connection = conn;
    cmd.CommandText = cmdText; if (trans != null)
    cmd.Transaction = trans; cmd.CommandType = cmdType; if (cmdParms != null) {
    foreach (SqlParameter parm in cmdParms)
    cmd.Parameters.Add(parm);
    }
    }
    }
    }
      

  29.   

    to: Reminisce(咕唧咕唧)我认真看了你推荐的PetShop代码,感觉很好,正准备借鉴一些经验,谢谢!to: stpangpang(胖在一方)看了你的分页存储过程,段代码只是针对一个表进行分页,不具有通用性。
    我的意思是:如果可以使用一个存储过程实现通用的分页操作,可是,由于表结构不同、返回结果集方法不同(视图、表、存储过程都可以返回结构集),这样一个存储过程不易实现。不知哪位高手有解决方案。昨天完成了手中的项目,看了一下Microsoft.ApplicationBlocks.Data的源码,很有收获,正准备对GAdoNet进行一些修改。
    感谢各位关注这个帖子,请继续发表意见。