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);代码比较简单就没有写注释。
这个思路用了一段时间了,现在精简成这个样子。我希望完善这个类,不知道现在是否有什么问题,或者缺少什么方法。
如果您有更好的思路希望不吝赐教。
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();
}
}
{
_conn.ConnectionString = ConnectString;
_conn.Open();
_conn.BeginTransaction();//这里还是独立出来好
}不过,这种数据库基本访问类应该建立在接口之上,也就是说,可以支持多种数据库和数据库访问类型,这个类写出来更有意义一些
不知道这样说搂主能不能明白,也就是说作的更加通用、灵活一些,这样比较好。比如:protected SqlConnection _conn;
这个定义,这是仅仅针对SQL Server的数据库连接对象,按照上面说的,建议这样定义:
protected IDbConnection _conn;还有其他的对象,建议也使用:IDbTransaction,IDbCommand....等等接口,然后建立一个对象工厂,在实例化这个基础访问类时,需要指定数据库访问对象的类型(OleDb的,还是MSSQL的,还是ODBC的,还是Oracle的等),然后对象工厂类生成一个具体的实例对象
方法里面
开启了一个事务这个如果不需要事务的话,可以不用的
所以这里建议
重载一个同名函数,里面不包含事务况且个人觉得open只是打开,没必要将事务也写在里面事务可以另外定义三个方法
begin rollback commit
{
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()能运行成功吗?
很感谢你的建议。用一个虚函数来初始化各个属性是个很好的方式,对于扩展也很有帮助。但是出于安全考虑,我没打算公开ConnectString,尽管可以通过sqlconnection也能返回connectstring.如果想公开的话,我会写到接口里。我做了protected的ConnectString实际是为了让子类调用。或者protected virtual更好一些。我会做这方面的修改。
很高兴你这么说,但是我对模式暂时还没有概念。
我想我已经在标题里说了,这仅仅是个数据库连接类。这是我在实际的应用当中写的,而且一直在用,慢慢演化到现在这个样子。我想要固定下来,以便于以后长期的使用,所以想请大家看看有没有什么硬伤。
前段时间我是在学习面向接口编程。因为我考虑到MySql,Sqlite等几种数据库连接的问题,想要降低数据连接层和业务层的耦合度,所以我想用接口来实现应该是最佳的方案。所以不仅仅是想封装不同的数据库,甚至是想要封装不同类的。
编程模式我会去学的。
没有生搬硬套,没有故弄玄虚。
呵呵,其实我对这个BeginTransaction还不是很理解,而且经过使用发现这个东西很画蛇添足。
其实我的本意就是写一个可以支持多种数据库和数据库访问类型
这个事务问题上的错误是由于我对事务的无知。
我正在补sql
mssql.Close();
mssql.Dispose();
我总感觉如果不在dispose之前关闭连接的话会在服务器端造成一个"无头"的空连接。所以在dispose里加入close方法主要是出于安全,用冗余的代码来保证资源的最小化。比如using的代码如果在末尾忘记关闭连接的话,dispose方法里的close就有用了。