以前只用一種數據庫,倒也無所謂,但是再數據庫切換的時候,發現代碼差不多呀。
最初,兩種數據庫,大不了寫兩個SqlHelper,但是多了也就發現代碼重用率太低了吧。
因此,下面的SqlHelper誕生了。
using System; using System.Collections; using System.Collections.Generic; using System.Data; using System.Linq; using System.Text; namespace WangSql.DBUtility { public static class SqlHelperExt { public static int AddRange(this IDataParameterCollection coll, IDataParameter[] par) { int i = 0; foreach (var item in par) { coll.Add(item); i++; } return i; } } #region SqlHelper public class SqlHelper { private IDbConnection conn = null; private IDbCommand cmd = null; private IDataReader dr = null; private DbType type = DbType.NONE; #region 創建數據庫連接 /// <summary> /// 創建數據庫連接 /// </summary> public SqlHelper(string connectionString) { conn = DBFactory.CreateDbConnection(type, connectionString); } #endregion #region 判斷並打開conn /// <summary> /// 判斷並打開conn /// </summary> /// <returns></returns> public IDbConnection CreatConn() { if (conn.State == ConnectionState.Closed) { conn.Open(); } return conn; } #endregion #region 執行查詢sql語句 /// <summary> /// 執行查詢sql語句 /// </summary> /// <param name="sql">查詢sql語句</param> /// <returns>返回一個表</returns> public DataTable ExecuteReader(string sql) { DataTable dt = new DataTable(); using (cmd = DBFactory.CreateDbCommand(sql, CreatConn())) { using (dr = cmd.ExecuteReader()) { dt.Load(dr); } } conn.Close(); return dt; } #endregion #region 執行查詢帶參的sql語句 /// <summary> /// 執行查詢帶參的sql語句 /// </summary> /// <param name="sql">查詢sql語句</param> /// <param name="par">sql語句中的參數</param> /// <returns>返回一個表</returns> public DataTable ExecuteReader(string sql, IDataParameter[] par) { DataTable dt = new DataTable(); using (cmd = DBFactory.CreateDbCommand(sql, CreatConn())) { cmd.Parameters.AddRange(par); using (dr = cmd.ExecuteReader()) { dt.Load(dr); } } conn.Close(); return dt; } public DataTable ExecuteReader(string sql, IDataParameter par) { DataTable dt = new DataTable(); using (cmd = DBFactory.CreateDbCommand(sql, CreatConn())) { cmd.Parameters.Add(par); using (dr = cmd.ExecuteReader()) { dt.Load(dr); } } conn.Close(); return dt; } #endregion #region 執行增,刪,改sql語句 /// <summary> /// 執行無參的增,刪,改sql語句 /// </summary> /// <param name="sql">增,刪,改的sql語句</param> /// <param name="par">sql語句中的參數</param> /// <returns>返回所影響的行數</returns> public int ExecuteNonQuery(string sql) { int result = 0; using (cmd = DBFactory.CreateDbCommand(sql, CreatConn())) { result = cmd.ExecuteNonQuery(); } conn.Close(); return result; } #endregion #region 執行帶參的增,刪,改sql語句 /// <summary> /// 執行帶參的增,刪,改sql語句 /// </summary> /// <param name="sql">增,刪,改的sql語句</param> /// <param name="par">sql語句中的參數</param> /// <returns>返回所影響的行數</returns> public int ExecuteNonQuery(string sql, IDbDataParameter[] par) { int result = 0; using (cmd = DBFactory.CreateDbCommand(sql, CreatConn())) { cmd.Parameters.AddRange(par); result = cmd.ExecuteNonQuery(); } conn.Close(); return result; } public int ExecuteNonQuery(string sql, IDbDataParameter par) { int result = 0; using (cmd = DBFactory.CreateDbCommand(sql, CreatConn())) { cmd.Parameters.Add(par); result = cmd.ExecuteNonQuery(); } conn.Close(); return result; } #endregion #region 事務 /// <summary> /// 執行多條SQL語句,實現數據庫事務。 /// </summary> /// <param name="SQLList">SQL語句的哈希表(key為sql語句,value是該語句的OleDbParameter[])</param> public bool ExecuteTransaction(Hashtable SqlList) { CreatConn(); using (IDbTransaction trans = conn.BeginTransaction()) { IDbCommand cmd = DBFactory.CreateDbCommand(type); try { //循環 foreach (DictionaryEntry myDE in SqlList) { string cmdText = myDE.Key.ToString(); IDbDataParameter[] cmdParms = (IDbDataParameter[])myDE.Value; PrepareCommand(cmd, conn, trans, cmdText, cmdParms); int val = cmd.ExecuteNonQuery(); cmd.Parameters.Clear(); } trans.Commit(); } catch { trans.Rollback(); return false; } finally { conn.Close(); } } return true; } private void PrepareCommand(IDbCommand cmd, IDbConnection conn, IDbTransaction trans, string cmdText, IDataParameter[] cmdParms) { CreatConn(); cmd.Connection = conn; cmd.CommandText = cmdText; if (trans != null) cmd.Transaction = trans; cmd.CommandType = CommandType.Text;//cmdType; if (cmdParms != null) cmd.Parameters.AddRange(cmdParms); } #endregion } #endregion }
上面是核心代碼,上面有個擴展。主要是是由於抽象類里面不包含AddRange方法。樓主也是懶得改原來的方法,也是為了和原來的SqlHelper保持一致,干脆就直接擴展了一個AddRange。
好了,既然是全是抽象參數,實際中,還是需要實例化具體某種數據庫的實例的,所以還需要一個創建各個數據庫實例的工廠了。
using MySql.Data.MySqlClient; using Oracle.DataAccess.Client; using System; using System.Collections.Generic; using System.Data; using System.Data.OleDb; using System.Data.SqlClient; using System.Data.SQLite; using System.Linq; using System.Text; namespace WangSql { public enum DbType { //Oracle,SqlServer,MySql,Access,SqlLite NONE, ORACLE, SQLSERVER, MYSQL, ACCESS, SQLLITE } public class DBFactory { public static IDbConnection CreateDbConnection(DbType type, string connectionString) { IDbConnection conn = null; switch (type) { case DbType.ORACLE: conn = new OracleConnection(connectionString); break; case DbType.SQLSERVER: conn = new SqlConnection(connectionString); break; case DbType.MYSQL: conn = new MySqlConnection(connectionString); break; case DbType.ACCESS: conn = new OleDbConnection(connectionString); break; case DbType.SQLLITE: conn = new SQLiteConnection(connectionString); break; case DbType.NONE: throw new Exception("未設置數據庫類型"); default: throw new Exception("不支持該數據庫類型"); } return conn; } public static IDbCommand CreateDbCommand(DbType type) { IDbCommand cmd = null; switch (type) { case DbType.ORACLE: cmd = new OracleCommand(); break; case DbType.SQLSERVER: cmd = new SqlCommand(); break; case DbType.MYSQL: cmd = new MySqlCommand(); break; case DbType.ACCESS: cmd = new OleDbCommand(); break; case DbType.SQLLITE: cmd = new SQLiteCommand(); break; case DbType.NONE: throw new Exception("未設置數據庫類型"); default: throw new Exception("不支持該數據庫類型"); } return cmd; } public static IDbCommand CreateDbCommand(string sql, IDbConnection conn) { DbType type = DbType.NONE; if (conn is OracleConnection) type = DbType.ORACLE; else if (conn is SqlConnection) type = DbType.SQLSERVER; else if (conn is MySqlConnection) type = DbType.MYSQL; else if (conn is OleDbConnection) type = DbType.ACCESS; else if (conn is SQLiteConnection) type = DbType.SQLLITE; IDbCommand cmd = null; switch (type) { case DbType.ORACLE: cmd = new OracleCommand(sql, (OracleConnection)conn); break; case DbType.SQLSERVER: cmd = new SqlCommand(sql, (SqlConnection)conn); break; case DbType.MYSQL: cmd = new MySqlCommand(sql, (MySqlConnection)conn); break; case DbType.ACCESS: cmd = new OleDbCommand(sql, (OleDbConnection)conn); break; case DbType.SQLLITE: cmd = new SQLiteCommand(sql, (SQLiteConnection)conn); break; case DbType.NONE: throw new Exception("未設置數據庫類型"); default: throw new Exception("不支持該數據庫類型"); } return cmd; } } }
哈哈,即使再來一個數據庫,你試試看,是不是很簡單呢。
對了,上面的SqlHelper再單例模式下是有問題的哦,這個請大家提出下好的建議。