本示例代码的关键是利用.net库自带的DbProviderFactory来生产数据库操作对象。
从下图中,可以看到其的多个核心方法,这些方法将在我们的超级DBHelper中使用。
仔细研究,你会发现每个数据库的官方支持dll都有一个Instance对象,这个对象都是继承了DbProviderFactory了。
因此利用这点,我们就可以实现兼容多种数据的超级DBHelper了。
以下为示例代码,仅供参考学习,代码只是我的ORM框架中的一个片段(其中暂时支持了SQLSERVER、MYSQL、SQLITE三种数据库,LoadDbProviderFactory方法是将封装在dll中的数据库操作dll反射加载实例化的方法。):
/// <summary> /// 超级数据库操作类 /// <para>2015年12月21日</para> /// <para>v1.0</para> /// <para>叶琪</para> /// </summary> public class DBHelper { #region 属性 private DbProviderFactory _DbFactory; private DBConfig mDBConfig; /// <summary> /// 数据库连接配置 /// </summary> public DBConfig DBConfig { get { return mDBConfig; } } /// <summary> /// 表示一组方法,这些方法用于创建提供程序对数据源类的实现的实例。 /// </summary> public DbProviderFactory DbFactory { get { return _DbFactory; } set { _DbFactory = value; } } #endregion #region 构造函数 public DBHelper(DBConfig aORMConfig) { mDBConfig = aORMConfig; switch (mDBConfig.DBType) { case ORMType.DBTypes.SQLSERVER: _DbFactory = System.Data.SqlClient.SqlClientFactory.Instance; break; case ORMType.DBTypes.MYSQL: LoadDbProviderFactory("MySql.Data.dll", "MySql.Data.MySqlClient.MySqlClientFactory"); break; case ORMType.DBTypes.SQLITE: LoadDbProviderFactory("System.Data.SQLite.dll", "System.Data.SQLite.SQLiteFactory"); break; } } /// <summary> /// 动态载入数据库封装库 /// </summary> /// <param name="aDLLName">数据库封装库文件名称</param> /// <param name="aFactoryName">工厂路径名称</param> private void LoadDbProviderFactory(string aDLLName, string aFactoryName) { string dllPath = string.Empty; if (System.AppDomain.CurrentDomain.RelativeSearchPath != null) { dllPath = System.AppDomain.CurrentDomain.RelativeSearchPath+"\\"+ aDLLName; } else { dllPath = System.AppDomain.CurrentDomain.BaseDirectory + aDLLName; } if (!File.Exists(dllPath)) {//文件不存在,从库资源中复制输出到基目录下 FileStream fdllFile = new FileStream(dllPath,FileMode.Create); byte[] dllData = null; if (aDLLName == "System.Data.SQLite.dll") { dllData = YFmk.ORM.Properties.Resources.System_Data_SQLite; } else if (aDLLName == "MySql.Data.dll") { dllData = YFmk.ORM.Properties.Resources.MySql_Data; } fdllFile.Write(dllData, 0, dllData.Length); fdllFile.Close(); } Assembly libAssembly = Assembly.LoadFile(dllPath); Type type = libAssembly.GetType(aFactoryName); foreach (FieldInfo fi in type.GetFields(BindingFlags.Static | BindingFlags.Public)) { if (fi.Name == "Instance") { _DbFactory = fi.GetValue(null) as DbProviderFactory; return; } } } #endregion #region 数据库操作 /// <summary> /// 执行一条计算查询结果语句,返回查询结果 /// </summary> /// <param name="aSQLWithParameter">SQL语句及参数</param> /// <returns>查询结果(object)</returns> public object GetSingle(SQLWithParameter aSQLWithParameter) { using (DbConnection conn = _DbFactory.CreateConnection()) { conn.ConnectionString = mDBConfig.ConnString; using (DbCommand cmd = _DbFactory.CreateCommand()) { PrepareCommand(cmd, conn, aSQLWithParameter.SQL.ToString(), aSQLWithParameter.Parameters); object obj = cmd.ExecuteScalar(); cmd.Parameters.Clear(); if ((Object.Equals(obj, null)) || (Object.Equals(obj, System.DBNull.Value))) { return null; } else { return obj; } } } } /// <summary> /// 执行SQL语句,返回影响的记录数 /// </summary> /// <param name="aSQL">SQL语句</param> /// <returns>影响的记录数</returns> public int ExecuteSql(string aSQL) { using (DbConnection conn = _DbFactory.CreateConnection()) { conn.ConnectionString = mDBConfig.ConnString; using (DbCommand cmd = _DbFactory.CreateCommand()) { PrepareCommand(cmd, conn, aSQL); int rows = cmd.ExecuteNonQuery(); cmd.Parameters.Clear(); return rows; } } } /// <summary> /// 执行SQL语句,返回影响的记录数 /// </summary> /// <param name="aSQLWithParameter">SQL语句及参数</param> /// <returns></returns> public int ExecuteSql(SQLWithParameter aSQLWithParameter) { using (DbConnection conn = _DbFactory.CreateConnection()) { conn.ConnectionString = mDBConfig.ConnString; using (DbCommand cmd = _DbFactory.CreateCommand()) { PrepareCommand(cmd, conn, aSQLWithParameter.SQL.ToString(), aSQLWithParameter.Parameters); int rows = cmd.ExecuteNonQuery(); cmd.Parameters.Clear(); return rows; } } } /// <summary> /// 执行多条SQL语句,实现数据库事务。 /// </summary> /// <param name="aSQLWithParameterList">参数化的SQL语句结构体对象集合</param> public string ExecuteSqlTran(List<SQLWithParameter> aSQLWithParameterList) { using (DbConnection conn = _DbFactory.CreateConnection()) { conn.ConnectionString = mDBConfig.ConnString; conn.Open(); DbTransaction fSqlTransaction = conn.BeginTransaction(); try { List<DbCommand> fTranCmdList = new List<DbCommand>(); //创建新的CMD DbCommand fFirstCMD = _DbFactory.CreateCommand(); fFirstCMD.Connection = conn; fFirstCMD.Transaction = fSqlTransaction; fTranCmdList.Add(fFirstCMD); int NowCmdIndex = 0;//当前执行的CMD索引值 int ExecuteCount = 0;//已经执行的CMD次数 StringBuilder fSQL = new StringBuilder(); foreach (SQLWithParameter fSQLWithParameter in aSQLWithParameterList) { fSQL.Append(fSQLWithParameter.SQL.ToString() + ";"); fTranCmdList[NowCmdIndex].Parameters.AddRange(fSQLWithParameter.Parameters.ToArray()); if (fTranCmdList[NowCmdIndex].Parameters.Count > 2000) { //参数达到2000个,执行一次CMD fTranCmdList[NowCmdIndex].CommandText = fSQL.ToString(); fTranCmdList[NowCmdIndex].ExecuteNonQuery(); DbCommand fNewCMD = _DbFactory.CreateCommand(); fNewCMD.Connection = conn; fNewCMD.Transaction = fSqlTransaction; fTranCmdList.Add(fNewCMD); NowCmdIndex++; ExecuteCount++; fSQL.Clear();//清空SQL } } if (ExecuteCount < fTranCmdList.Count) {//已执行CMD次数小于总CMD数,执行最后一条CMD fTranCmdList[fTranCmdList.Count - 1].CommandText = fSQL.ToString(); fTranCmdList[fTranCmdList.Count - 1].ExecuteNonQuery(); } fSqlTransaction.Commit(); return null; } catch (Exception ex) { fSqlTransaction.Rollback(); StringBuilder fSQL = new StringBuilder(); foreach (SQLWithParameter fSQLWithParameter in aSQLWithParameterList) { fSQL.Append(fSQLWithParameter.SQL.ToString() + ";"); } YFmk.Lib.LocalLog.WriteByDate(fSQL.ToString()+" 错误:"+ex.Message, "ORM"); return ex.Message; } } } /// <summary> /// 执行查询语句,返回DataSet /// </summary> /// <param name="SQLString">查询语句</param> /// <returns>DataSet</returns> public DataSet Query(string SQLString) { using (DbConnection conn = _DbFactory.CreateConnection()) { conn.ConnectionString = mDBConfig.ConnString; using (DbCommand cmd = _DbFactory.CreateCommand()) { PrepareCommand(cmd, conn, SQLString); using (DbDataAdapter da = _DbFactory.CreateDataAdapter()) { da.SelectCommand = cmd; DataSet ds = new DataSet(); try { da.Fill(ds, "ds"); cmd.Parameters.Clear(); } catch (Exception ex) { } return ds; } } } } /// <summary> /// 执行查询语句,返回DataSet /// </summary> /// <param name="aSQLWithParameter">查询语句</param> /// <returns>DataSet</returns> public DataSet Query(SQLWithParameter aSQLWithParameter) { using (DbConnection conn = _DbFactory.CreateConnection()) { conn.ConnectionString = mDBConfig.ConnString; using (DbCommand cmd = _DbFactory.CreateCommand()) { PrepareCommand(cmd, conn, aSQLWithParameter.SQL.ToString(), aSQLWithParameter.Parameters); using (DbDataAdapter da = _DbFactory.CreateDataAdapter()) { da.SelectCommand = cmd; DataSet ds = new DataSet(); da.Fill(ds, "ds"); cmd.Parameters.Clear(); return ds; } } } } #endregion #region 私有函数 private void PrepareCommand(DbCommand cmd, DbConnection conn, string cmdText) { if (conn.State != ConnectionState.Open) conn.Open(); cmd.Connection = conn; cmd.CommandText = cmdText; } private void PrepareCommand(DbCommand cmd, DbConnection conn, string cmdText, List<DbParameter> cmdParms) { if (conn.State != ConnectionState.Open) conn.Open(); cmd.Connection = conn; cmd.CommandText = cmdText; if (cmdParms != null && cmdParms.Count>0) { cmd.Parameters.AddRange(cmdParms.ToArray()); } } #endregion
摘自:http://blog.csdn.net/sqqyq/article/details/50374864