public interface IMSSQL : IDisposable
    {
        void Open();
        void Close();
        SqlConnection Connection { get; }
    }
    public abstract class MSSQLBase
    {
        protected string _DataSource;
        protected string _UserID;
        protected string _Password;
        protected string _InitialCatalog;
        protected bool _Pooling;
        protected int _MaxPoolSize;
        protected SqlConnection _conn;        protected string ConnectString
        {
            get
            {
                SqlConnectionStringBuilder s = new SqlConnectionStringBuilder();
                s.DataSource = _DataSource;
                s.UserID = _UserID;
                s.Password = _Password;
                s.InitialCatalog = _InitialCatalog;
                //s.Pooling = _Pooling;
                //s.MaxPoolSize = _MaxPoolSize;
                return s.ConnectionString;
            }
        }
        public void Open()
        {
            _conn.ConnectionString = ConnectString;
            _conn.Open();
            _conn.BeginTransaction();
        }
        public void Close()
        {
            if (_conn.State != System.Data.ConnectionState.Closed)
                _conn.Close();
        }
        public void Dispose()
        {
            if (_conn.State != System.Data.ConnectionState.Closed)
                _conn.Close();
            _conn.Dispose();
        }
        public SqlConnection Connection
        {
            get { return _conn; }
        }
    }
    public class MSSQL : MSSQLBase, IMSSQL
    {
        public MSSQL(string dataSource, string initialCatalog, string userID, string password)
        {
            _conn = new SqlConnection();
            _DataSource = dataSource;
            _InitialCatalog = initialCatalog;
            _UserID = userID;
            _Password = password;
            //_MaxPoolSize = 100;
            //_Pooling = true;
        }
    }
    public class MSSQL_Local : MSSQLBase, IMSSQL
    {
        public MSSQL_Local()
        {
            _conn = new SqlConnection();
            _DataSource = Properties.Resources.LocalSqlConnectiong_Datasource;
            _InitialCatalog = Properties.Resources.LocalSqlConnectiong_InitialCatalog;
            _UserID = Properties.Resources.LocalSqlConnectiong_UserID;
            _Password = Properties.Resources.LocalSqlConnectiong_Password;
            //_MaxPoolSize = int.Parse(Properties.Resources.LocalSqlConnectiong_MaxPoolSize);
        }
    }因为是写成类库了,所以在MSSQL_Local类中使用资源中定义的参数来赋值。
具体使用的方法:        public static int Command(string sql, IMSSQL mssql)
        {
            mssql.Open();
            SqlCommand sc = mssql.Connection.CreateCommand();
            sc.CommandText = sql;
            int i = sc.ExecuteNonQuery();
            sc.Dispose();
            mssql.Close();
            mssql.Dispose();
            return i;
        }
        Command("insert ...", new MSSQL_Local() as IMSSQL);代码比较简单就没有写注释。
这个思路用了一段时间了,现在精简成这个样子。我希望完善这个类,不知道现在是否有什么问题,或者缺少什么方法。
如果您有更好的思路希望不吝赐教。

解决方案 »

  1.   

    基本没什么问题,但:
    protected string ConnectString
            {
                get
                {
                    SqlConnectionStringBuilder s = new SqlConnectionStringBuilder();
                    s.DataSource = _DataSource;
                    s.UserID = _UserID;
                    s.Password = _Password;
                    s.InitialCatalog = _InitialCatalog;
                    //s.Pooling = _Pooling;
                    //s.MaxPoolSize = _MaxPoolSize;
                    return s.ConnectionString;
                }
            }
            public void Open()
            {
                _conn.ConnectionString = ConnectString;
                _conn.Open();
                _conn.BeginTransaction();
            }
    应该改为:public MSSQLBase()
    {
      this.InitConnection()
    }
    protected virtual void InitConnection()
    {
     _conn = new SqlConnection();  SqlConnectionStringBuilder s = new SqlConnectionStringBuilder();
                    s.DataSource = _DataSource;
                    s.UserID = _UserID;
                    s.Password = _Password;
                    s.InitialCatalog = _InitialCatalog;
                    //s.Pooling = _Pooling;
                    //s.MaxPoolSize = _MaxPoolSize;
      _conn.ConnectionString = s.ConnectionString;}
    public string ConnectString
    {
     get{return this.Connection.ConnectString;}
    public SqlConnection Connection
    {
     get{
     if(_conn == null) this.InitConnection();
      return _conn;}
    }
    public void Open()
    {
      this.Connection.Open();
      this.Connection.BeginTransaction();
    }public class MSSQL : MSSQLBase, IMSSQL
        {
            public MSSQL(string dataSource, string initialCatalog, string userID, string password)
            {
                _DataSource = dataSource;
                _InitialCatalog = initialCatalog;
                _UserID = userID;
                _Password = password;
                //_MaxPoolSize = 100;
                //_Pooling = true;
                this.InitConnection();
            }
        }
        public class MSSQL_Local : MSSQLBase, IMSSQL
        {
            public MSSQL_Local()
            {
               _DataSource = Properties.Resources.LocalSqlConnectiong_Datasource;
                _InitialCatalog = Properties.Resources.LocalSqlConnectiong_InitialCatalog;
                _UserID = Properties.Resources.LocalSqlConnectiong_UserID;
                _Password = Properties.Resources.LocalSqlConnectiong_Password;
                //_MaxPoolSize = int.Parse(Properties.Resources.LocalSqlConnectiong_MaxPoolSize);
                this.InitConnection();
            }
        }
      

  2.   

            public void Open()
            {
                _conn.ConnectionString = ConnectString;
                _conn.Open();
                _conn.BeginTransaction();//这里还是独立出来好
            }不过,这种数据库基本访问类应该建立在接口之上,也就是说,可以支持多种数据库和数据库访问类型,这个类写出来更有意义一些
    不知道这样说搂主能不能明白,也就是说作的更加通用、灵活一些,这样比较好。比如:protected SqlConnection _conn;
    这个定义,这是仅仅针对SQL Server的数据库连接对象,按照上面说的,建议这样定义:
    protected IDbConnection _conn;还有其他的对象,建议也使用:IDbTransaction,IDbCommand....等等接口,然后建立一个对象工厂,在实例化这个基础访问类时,需要指定数据库访问对象的类型(OleDb的,还是MSSQL的,还是ODBC的,还是Oracle的等),然后对象工厂类生成一个具体的实例对象
      

  3.   

    MSSQLBase.Open()
    方法里面
    开启了一个事务这个如果不需要事务的话,可以不用的
    所以这里建议
    重载一个同名函数,里面不包含事务况且个人觉得open只是打开,没必要将事务也写在里面事务可以另外定义三个方法
    begin rollback commit
      

  4.   

    public static int Command(string sql, IMSSQL mssql)
            {
                mssql.Open();
                SqlCommand sc = mssql.Connection.CreateCommand();
                sc.CommandText = sql;
                int i = sc.ExecuteNonQuery();
                sc.Dispose();
                mssql.Close();
                mssql.Dispose();
                return i;
            }
    mssql.Open();这里面开了事务_conn.BeginTransaction();
    上面的Command()方法中,你直接mssql.Close();
    Close()方法中又没有提交事务。默认的DBConnection.Close()方法是要RollBack挂起的事务。
    你这个Command()能运行成功吗?
      

  5.   


    很感谢你的建议。用一个虚函数来初始化各个属性是个很好的方式,对于扩展也很有帮助。但是出于安全考虑,我没打算公开ConnectString,尽管可以通过sqlconnection也能返回connectstring.如果想公开的话,我会写到接口里。我做了protected的ConnectString实际是为了让子类调用。或者protected virtual更好一些。我会做这方面的修改。
      

  6.   


    很高兴你这么说,但是我对模式暂时还没有概念。
    我想我已经在标题里说了,这仅仅是个数据库连接类。这是我在实际的应用当中写的,而且一直在用,慢慢演化到现在这个样子。我想要固定下来,以便于以后长期的使用,所以想请大家看看有没有什么硬伤。
    前段时间我是在学习面向接口编程。因为我考虑到MySql,Sqlite等几种数据库连接的问题,想要降低数据连接层和业务层的耦合度,所以我想用接口来实现应该是最佳的方案。所以不仅仅是想封装不同的数据库,甚至是想要封装不同类的。
    编程模式我会去学的。
    没有生搬硬套,没有故弄玄虚。
      

  7.   


    呵呵,其实我对这个BeginTransaction还不是很理解,而且经过使用发现这个东西很画蛇添足。
    其实我的本意就是写一个可以支持多种数据库和数据库访问类型
      

  8.   


    这个事务问题上的错误是由于我对事务的无知。
    我正在补sql
      

  9.   

    你的Dispose()方法就调用了Close()的处理。
                mssql.Close();
                mssql.Dispose();
      

  10.   


    我总感觉如果不在dispose之前关闭连接的话会在服务器端造成一个"无头"的空连接。所以在dispose里加入close方法主要是出于安全,用冗余的代码来保证资源的最小化。比如using的代码如果在末尾忘记关闭连接的话,dispose方法里的close就有用了。