不知道可能稱的上是ORM,其實就是一個DBHelper。看到網上不少人寫自己的ORM,但我覺得都不太好。
我這個ORM,學習成本非常低,常用的方法僅有幾個,在使用的過程中,你不需要有太多要注意的地方,也不會有“我怎樣實現連表查詢”的疑問。反射犧牲一些性能,但是降低了實現和使用的復雜度。
支持Oracle、MSSQL、MySQL、SQLite四種數據庫,並配有Model生成器。
Model層的設計:
Models目錄中的類及其屬性和數據庫中的表和字段是完全對應的,Models全部由生成器生成,並且不允許手動修改。ExtModels目錄中的類是擴展類,主要用於查詢與顯示,比如表中存的是code,但你需要關聯查詢另一張表中的name,就可以在這個擴展類中擴展一個用於顯示的name字段。Models和ExtModels目錄的中類都是partial修飾。
例(由於是SQLite數據庫,所以生成的Model沒有注釋,其它三種數據庫有注釋):
Model:
using System; using System.Collections.Generic; using System.Linq; namespace Models { /// <summary> /// /// </summary> [Serializable] public partial class BS_Template { /// <summary> /// /// </summary> [IsId] [IsDBField] public string id { get; set; } /// <summary> /// /// </summary> [IsDBField] public string typeCode { get; set; } /// <summary> /// /// </summary> [IsDBField] public string type { get; set; } /// <summary> /// /// </summary> [IsDBField] public string code { get; set; } /// <summary> /// /// </summary> [IsDBField] public string name { get; set; } /// <summary> /// /// </summary> [IsDBField] public string path { get; set; } /// <summary> /// /// </summary> [IsDBField] public string folder { get; set; } /// <summary> /// /// </summary> [IsDBField] public string remarks { get; set; } } } View CodeExtModel:
using System; using System.Collections.Generic; using System.Linq; namespace Models { /// <summary> /// /// </summary> public partial class BS_Template { //暫沒有擴展字段 } } View Code
DBHelper代碼:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Configuration; using System.Data; using System.Data.Common; using System.Data.Objects.DataClasses; using System.Data.OracleClient; using System.Data.SqlClient; using System.Data.SQLite; using System.Reflection; using System.Text; using Models; using MySql.Data.MySqlClient; namespace DBUtil { /// <summary> /// 數據庫操作類 /// 2016年09月09日 /// </summary> public class DBHelper { #region 變量 /// <summary> /// 數據庫類型 /// </summary> private static string m_DBType = ConfigurationManager.AppSettings["DBType"]; /// <summary> /// 數據庫類型 /// </summary> private static bool m_AutoIncrement = ConfigurationManager.AppSettings["AutoIncrement"].ToLower() == "true" ? true : false; /// <summary> /// 數據庫連接字符串 /// </summary> private static string m_ConnectionString = ConfigurationManager.ConnectionStrings["DefaultConnection"].ToString(); /// <summary> /// 事務 /// </summary> [ThreadStatic] private static DbTransaction m_Tran; /// <summary> /// 帶參數的SQL插入和修改語句中,參數前面的符號 /// </summary> private static string m_ParameterMark = GetParameterMark(); #endregion #region 構造函數 /// <summary> /// 數據庫操作類 /// </summary> public DBHelper() { } #endregion #region 生成變量 #region 生成 IDbCommand /// <summary> /// 生成 IDbCommand /// </summary> private DbCommand GetCommand() { DbCommand command = null; switch (m_DBType) { case "oracle": command = new OracleCommand(); break; case "mssql": command = new SqlCommand(); break; case "mysql": command = new MySqlCommand(); break; case "sqlite": command = new SQLiteCommand(); break; } return command; } /// <summary> /// 生成 IDbCommand /// </summary> private DbCommand GetCommand(string sql, DbConnection conn) { DbCommand command = null; switch (m_DBType) { case "oracle": command = new OracleCommand(sql); command.Connection = conn; break; case "mssql": command = new SqlCommand(sql); command.Connection = conn; break; case "mysql": command = new MySqlCommand(sql); command.Connection = conn; break; case "sqlite": command = new SQLiteCommand(sql); command.Connection = conn; break; } return command; } #endregion #region 生成 IDbConnection /// <summary> /// 生成 IDbConnection /// </summary> private static DbConnection GetConnection() { DbConnection conn = null; switch (m_DBType) { case "oracle": conn = new OracleConnection(m_ConnectionString); break; case "mssql": conn = new SqlConnection(m_ConnectionString); break; case "mysql": conn = new MySqlConnection(m_ConnectionString); break; case "sqlite": conn = new SQLiteConnection(m_ConnectionString); break; } return conn; } #endregion #region 生成 IDbDataAdapter /// <summary> /// 生成 IDbDataAdapter /// </summary> private DbDataAdapter GetDataAdapter(DbCommand cmd) { DbDataAdapter dataAdapter = null; switch (m_DBType) { case "oracle": dataAdapter = new OracleDataAdapter(); dataAdapter.SelectCommand = cmd; break; case "mssql": dataAdapter = new SqlDataAdapter(); dataAdapter.SelectCommand = cmd; break; case "mysql": dataAdapter = new MySqlDataAdapter(); dataAdapter.SelectCommand = cmd; break; case "sqlite": dataAdapter = new SQLiteDataAdapter(); dataAdapter.SelectCommand = cmd; break; } return dataAdapter; } #endregion #region 生成 m_ParameterMark /// <summary> /// 生成 m_ParameterMark /// </summary> private static string GetParameterMark() { switch (m_DBType) { case "oracle": return ":"; case "mssql": return "@"; case "mysql": return "@"; case "sqlite": return ":"; } return ":"; } #endregion #endregion #region 基礎方法 #region 執行簡單SQL語句 #region Exists public bool Exists(string sqlString) { using (DbConnection conn = GetConnection()) { using (DbCommand cmd = GetCommand(sqlString, conn)) { try { conn.Open(); object obj = cmd.ExecuteScalar(); if ((Object.Equals(obj, null)) || (Object.Equals(obj, System.DBNull.Value))) { return false; } else { return true; } } catch (Exception ex) { throw ex; } finally { cmd.Dispose(); conn.Close(); } } } } #endregion #region 執行SQL語句,返回影響的記錄數 /// <summary> /// 執行SQL語句,返回影響的記錄數 /// </summary> /// <param name="sqlString">SQL語句</param> /// <returns>影響的記錄數</returns> public int ExecuteSql(string sqlString) { DbConnection conn = m_Tran == null ? GetConnection() : m_Tran.Connection; using (DbCommand cmd = GetCommand(sqlString, conn)) { try { if (conn.State != ConnectionState.Open) conn.Open(); if (m_Tran != null) cmd.Transaction = m_Tran; int rows = cmd.ExecuteNonQuery(); return rows; } catch (Exception ex) { throw new Exception(ex.Message); } finally { cmd.Dispose(); if (m_Tran == null) conn.Close(); } } } #endregion #region 執行一條計算查詢結果語句,返回查詢結果 /// <summary> /// 執行一條計算查詢結果語句,返回查詢結果(object) /// </summary> /// <param name="sqlString">計算查詢結果語句</param> /// <returns>查詢結果(object)</returns> public object GetSingle(string sqlString) { using (DbConnection conn = GetConnection()) { using (DbCommand cmd = GetCommand(sqlString, conn)) { try { if (conn.State != ConnectionState.Open) conn.Open(); object obj = cmd.ExecuteScalar(); if ((Object.Equals(obj, null)) || (Object.Equals(obj, System.DBNull.Value))) { return null; } else { return obj; } } catch (Exception ex) { throw ex; } finally { cmd.Dispose(); } } } } #endregion #region 執行查詢語句,返回IDataReader /// <summary> /// 執行查詢語句,返回IDataReader ( 注意:調用該方法後,一定要對IDataReader進行Close ) /// </summary> /// <param name="sqlString">查詢語句</param> /// <returns>IDataReader</returns> public DbDataReader ExecuteReader(string sqlString) { DbConnection conn = GetConnection(); DbCommand cmd = GetCommand(sqlString, conn); try { if (conn.State != ConnectionState.Open) conn.Open(); DbDataReader myReader = cmd.ExecuteReader(CommandBehavior.CloseConnection); return myReader; } catch (Exception ex) { throw ex; } } #endregion #region 執行查詢語句,返回DataSet /// <summary> /// 執行查詢語句,返回DataSet /// </summary> /// <param name="sqlString">查詢語句</param> /// <returns>DataSet</returns> public DataSet Query(string sqlString) { using (DbConnection conn = GetConnection()) { DataSet ds = new DataSet(); try { conn.Open(); using (DbCommand cmd = GetCommand(sqlString, conn)) { DbDataAdapter adapter = GetDataAdapter(cmd); adapter.Fill(ds, "ds"); } } catch (Exception ex) { throw ex; } finally { conn.Close(); } return ds; } } #endregion #endregion #region 執行帶參數的SQL語句 #region 執行SQL語句,返回影響的記錄數 /// <summary> /// 執行SQL語句,返回影響的記錄數 /// </summary> /// <param name="SQLString">SQL語句</param> /// <returns>影響的記錄數</returns> public int ExecuteSql(string SQLString, params DbParameter[] cmdParms) { DbConnection conn = m_Tran == null ? GetConnection() : m_Tran.Connection; using (DbCommand cmd = GetCommand()) { try { PrepareCommand(cmd, conn, m_Tran, SQLString, cmdParms); int rows = cmd.ExecuteNonQuery(); cmd.Parameters.Clear(); return rows; } catch (Exception ex) { throw ex; } finally { cmd.Dispose(); if (m_Tran == null) conn.Close(); } } } #endregion #region 執行查詢語句,返回IDataReader /// <summary> /// 執行查詢語句,返回IDataReader ( 注意:調用該方法後,一定要對IDataReader進行Close ) /// </summary> /// <param name="strSQL">查詢語句</param> /// <returns>IDataReader</returns> public DbDataReader ExecuteReader(string sqlString, params DbParameter[] cmdParms) { DbConnection conn = GetConnection(); DbCommand cmd = GetCommand(); try { PrepareCommand(cmd, conn, null, sqlString, cmdParms); DbDataReader myReader = cmd.ExecuteReader(CommandBehavior.CloseConnection); cmd.Parameters.Clear(); return myReader; } catch (Exception ex) { throw ex; } } #endregion #region 執行查詢語句,返回DataSet /// <summary> /// 執行查詢語句,返回DataSet /// </summary> /// <param name="sqlString">查詢語句</param> /// <returns>DataSet</returns> public DataSet Query(string sqlString, params DbParameter[] cmdParms) { DbConnection conn = GetConnection(); DbCommand cmd = GetCommand(); PrepareCommand(cmd, conn, null, sqlString, cmdParms); using (DbDataAdapter da = GetDataAdapter(cmd)) { DataSet ds = new DataSet(); try { da.Fill(ds, "ds"); cmd.Parameters.Clear(); } catch (Exception ex) { throw ex; } finally { cmd.Dispose(); conn.Close(); } return ds; } } #endregion #region PrepareCommand private void PrepareCommand(DbCommand cmd, DbConnection conn, DbTransaction trans, string cmdText, DbParameter[] cmdParms) { if (conn.State != ConnectionState.Open) conn.Open(); cmd.Connection = conn; cmd.CommandText = cmdText; if (trans != null) cmd.Transaction = trans; cmd.CommandType = CommandType.Text; if (cmdParms != null) { foreach (DbParameter parm in cmdParms) { cmd.Parameters.Add(parm); } } } #endregion #endregion #endregion #region 增刪改查 #region 獲取最大編號 /// <summary> /// 獲取最大編號 /// </summary> /// <typeparam name="T">實體Model</typeparam> /// <param name="key">主鍵</param> public int GetMaxID<T>(string key) { Type type = typeof(T); string sql = null; switch (m_DBType) { case "oracle": sql = string.Format("SELECT Max({0}) FROM {1}", key, type.Name); break; case "mssql": sql = string.Format("SELECT Max({0}) FROM {1}", key, type.Name); break; case "mysql": sql = string.Format("SELECT Max({0}) FROM {1}", key, type.Name); break; case "sqlite": sql = string.Format("SELECT Max(cast({0} as int)) FROM {1}", key, type.Name); break; } using (DbConnection conn = GetConnection()) { using (IDbCommand cmd = GetCommand(sql, conn)) { try { conn.Open(); object obj = cmd.ExecuteScalar(); if ((Object.Equals(obj, null)) || (Object.Equals(obj, System.DBNull.Value))) { return 1; } else { return int.Parse(obj.ToString()) + 1; } } catch (Exception ex) { throw ex; } finally { cmd.Dispose(); conn.Close(); } } } } #endregion #region 添加 /// <summary> /// 添加 /// </summary> public void Insert(object obj) { Insert(obj, m_AutoIncrement); } /// <summary> /// 添加 /// </summary> public void Insert(object obj, bool autoIncrement) { StringBuilder strSql = new StringBuilder(); Type type = obj.GetType(); strSql.Append(string.Format("insert into {0}(", type.Name)); PropertyInfo[] propertyInfoList = GetEntityProperties(type); List<string> propertyNameList = new List<string>(); int savedCount = 0; foreach (PropertyInfo propertyInfo in propertyInfoList) { if (propertyInfo.GetCustomAttributes(typeof(IsIdAttribute), false).Length > 0 && autoIncrement) return; if (propertyInfo.GetCustomAttributes(typeof(IsDBFieldAttribute), false).Length > 0) { propertyNameList.Add(propertyInfo.Name); savedCount++; } } strSql.Append(string.Format("{0})", string.Join(",", propertyNameList.ToArray()))); strSql.Append(string.Format(" values ({0})", string.Join(",", propertyNameList.ConvertAll<string>(a => m_ParameterMark + a).ToArray()))); SQLiteParameter[] parameters = new SQLiteParameter[savedCount]; int k = 0; for (int i = 0; i < propertyInfoList.Length && savedCount > 0; i++) { PropertyInfo propertyInfo = propertyInfoList[i]; if (propertyInfo.GetCustomAttributes(typeof(IsIdAttribute), false).Length > 0 && autoIncrement) return; if (propertyInfo.GetCustomAttributes(typeof(IsDBFieldAttribute), false).Length > 0) { object val = propertyInfo.GetValue(obj, null); SQLiteParameter param = new SQLiteParameter(m_ParameterMark + propertyInfo.Name, val == null ? DBNull.Value : val); parameters[k++] = param; } } ExecuteSql(strSql.ToString(), parameters); } #endregion #region 修改 /// <summary> /// 修改 /// </summary> public void Update(object obj) { object oldObj = Find(obj, false); if (oldObj == null) throw new Exception("無法獲取到舊數據"); StringBuilder strSql = new StringBuilder(); Type type = obj.GetType(); strSql.Append(string.Format("update {0} ", type.Name)); PropertyInfo[] propertyInfoList = GetEntityProperties(type); List<string> propertyNameList = new List<string>(); int savedCount = 0; foreach (PropertyInfo propertyInfo in propertyInfoList) { if (propertyInfo.GetCustomAttributes(typeof(IsDBFieldAttribute), false).Length > 0) { object oldVal = propertyInfo.GetValue(oldObj, null); object val = propertyInfo.GetValue(obj, null); if (!object.Equals(oldVal, val)) { propertyNameList.Add(propertyInfo.Name); savedCount++; } } } strSql.Append(string.Format(" set ")); SQLiteParameter[] parameters = new SQLiteParameter[savedCount]; StringBuilder sbPros = new StringBuilder(); int k = 0; for (int i = 0; i < propertyInfoList.Length && savedCount > 0; i++) { PropertyInfo propertyInfo = propertyInfoList[i]; if (propertyInfo.GetCustomAttributes(typeof(IsDBFieldAttribute), false).Length > 0) { object oldVal = propertyInfo.GetValue(oldObj, null); object val = propertyInfo.GetValue(obj, null); if (!object.Equals(oldVal, val)) { sbPros.Append(string.Format(" {0}=:{0},", propertyInfo.Name)); SQLiteParameter param = new SQLiteParameter(m_ParameterMark + propertyInfo.Name, val == null ? DBNull.Value : val); parameters[k++] = param; } } } if (sbPros.Length > 0) { strSql.Append(sbPros.ToString(0, sbPros.Length - 1)); } strSql.Append(string.Format(" where {0}='{1}'", GetIdName(obj.GetType()), GetIdVal(obj).ToString())); if (savedCount > 0) { ExecuteSql(strSql.ToString(), parameters); } } #endregion #region 刪除 /// <summary> /// 根據Id刪除 /// </summary> public void Delete<T>(int id) { Type type = typeof(T); StringBuilder sbSql = new StringBuilder(); sbSql.Append(string.Format("delete from {0} where {2}='{1}'", type.Name, id, GetIdName(type))); ExecuteSql(sbSql.ToString()); } /// <summary> /// 根據Id集合刪除 /// </summary> public void BatchDelete<T>(string ids) { if (string.IsNullOrWhiteSpace(ids)) return; Type type = typeof(T); StringBuilder sbSql = new StringBuilder(); sbSql.Append(string.Format("delete from {0} where {2} in ({1})", type.Name, ids, GetIdName(type))); ExecuteSql(sbSql.ToString()); } /// <summary> /// 根據條件刪除 /// </summary> public void Delete<T>(string conditions) { if (string.IsNullOrWhiteSpace(conditions)) return; Type type = typeof(T); StringBuilder sbSql = new StringBuilder(); sbSql.Append(string.Format("delete from {0} where {1}", type.Name, conditions)); ExecuteSql(sbSql.ToString()); } #endregion #region 獲取實體 #region 根據實體獲取實體 /// <summary> /// 根據實體獲取實體 /// </summary> private object Find(object obj, bool readCache = true) { Type type = obj.GetType(); object result = Activator.CreateInstance(type); bool hasValue = false; IDataReader rd = null; string sql = string.Format("select * from {0} where {2}='{1}'", type.Name, GetIdVal(obj), GetIdName(obj.GetType())); try { rd = ExecuteReader(sql); PropertyInfo[] propertyInfoList = GetEntityProperties(type); int fcnt = rd.FieldCount; List<string> fileds = new List<string>(); for (int i = 0; i < fcnt; i++) { fileds.Add(rd.GetName(i).ToUpper()); } while (rd.Read()) { hasValue = true; IDataRecord record = rd; foreach (PropertyInfo pro in propertyInfoList) { if (!fileds.Contains(pro.Name.ToUpper()) || record[pro.Name] == DBNull.Value) { continue; } pro.SetValue(result, record[pro.Name] == DBNull.Value ? null : getReaderValue(record[pro.Name], pro.PropertyType), null); } } } catch (Exception ex) { throw ex; } finally { if (rd != null && !rd.IsClosed) { rd.Close(); rd.Dispose(); } } if (hasValue) { return result; } else { return null; } } #endregion #region 根據Id獲取實體 /// <summary> /// 根據Id獲取實體 /// </summary> private object FindById(Type type, int id) { object result = Activator.CreateInstance(type); IDataReader rd = null; bool hasValue = false; string sql = string.Format("select * from {0} where {2}='{1}'", type.Name, id, GetIdName(type)); try { rd = ExecuteReader(sql); PropertyInfo[] propertyInfoList = GetEntityProperties(type); int fcnt = rd.FieldCount; List<string> fileds = new List<string>(); for (int i = 0; i < fcnt; i++) { fileds.Add(rd.GetName(i).ToUpper()); } while (rd.Read()) { hasValue = true; IDataRecord record = rd; foreach (PropertyInfo pro in propertyInfoList) { if (!fileds.Contains(pro.Name.ToUpper()) || record[pro.Name] == DBNull.Value) { continue; } pro.SetValue(result, record[pro.Name] == DBNull.Value ? null : getReaderValue(record[pro.Name], pro.PropertyType), null); } } } catch (Exception ex) { throw ex; } finally { if (rd != null && !rd.IsClosed) { rd.Close(); rd.Dispose(); } } if (hasValue) { return result; } else { return null; } } #endregion #region 根據Id獲取實體 /// <summary> /// 根據Id獲取實體 /// </summary> public T FindById<T>(string id) where T : new() { Type type = typeof(T); T result = (T)Activator.CreateInstance(type); IDataReader rd = null; bool hasValue = false; string sql = string.Format("select * from {0} where {2}='{1}'", type.Name, id, GetIdName(type)); try { rd = ExecuteReader(sql); PropertyInfo[] propertyInfoList = GetEntityProperties(type); int fcnt = rd.FieldCount; List<string> fileds = new List<string>(); for (int i = 0; i < fcnt; i++) { fileds.Add(rd.GetName(i).ToUpper()); } while (rd.Read()) { hasValue = true; IDataRecord record = rd; foreach (PropertyInfo pro in propertyInfoList) { if (!fileds.Contains(pro.Name.ToUpper()) || record[pro.Name] == DBNull.Value) { continue; } pro.SetValue(result, record[pro.Name] == DBNull.Value ? null : getReaderValue(record[pro.Name], pro.PropertyType), null); } } } catch (Exception ex) { throw ex; } finally { if (rd != null && !rd.IsClosed) { rd.Close(); rd.Dispose(); } } if (hasValue) { return result; } else { return default(T); } } #endregion #region 根據sql獲取實體 /// <summary> /// 根據sql獲取實體 /// </summary> public T FindBySql<T>(string sql) where T : new() { Type type = typeof(T); T result = (T)Activator.CreateInstance(type); IDataReader rd = null; bool hasValue = false; try { rd = ExecuteReader(sql); PropertyInfo[] propertyInfoList = GetEntityProperties(type); int fcnt = rd.FieldCount; List<string> fileds = new List<string>(); for (int i = 0; i < fcnt; i++) { fileds.Add(rd.GetName(i).ToUpper()); } while (rd.Read()) { hasValue = true; IDataRecord record = rd; foreach (PropertyInfo pro in propertyInfoList) { if (!fileds.Contains(pro.Name.ToUpper()) || record[pro.Name] == DBNull.Value) { continue; } pro.SetValue(result, record[pro.Name] == DBNull.Value ? null : getReaderValue(record[pro.Name], pro.PropertyType), null); } } } catch (Exception ex) { throw ex; } finally { if (rd != null && !rd.IsClosed) { rd.Close(); rd.Dispose(); } } if (hasValue) { return result; } else { return default(T); } } #endregion #endregion #region 獲取列表 /// <summary> /// 獲取列表 /// </summary> public List<T> FindListBySql<T>(string sql) where T : new() { List<T> list = new List<T>(); object obj; IDataReader rd = null; try { rd = ExecuteReader(sql); if (typeof(T) == typeof(int)) { while (rd.Read()) { list.Add((T)rd[0]); } } else if (typeof(T) == typeof(string)) { while (rd.Read()) { list.Add((T)rd[0]); } } else { PropertyInfo[] propertyInfoList = (typeof(T)).GetProperties(); int fcnt = rd.FieldCount; List<string> fileds = new List<string>(); for (int i = 0; i < fcnt; i++) { fileds.Add(rd.GetName(i).ToUpper()); } while (rd.Read()) { IDataRecord record = rd; obj = new T(); foreach (PropertyInfo pro in propertyInfoList) { if (!fileds.Contains(pro.Name.ToUpper()) || record[pro.Name] == DBNull.Value) { continue; } pro.SetValue(obj, record[pro.Name] == DBNull.Value ? null : getReaderValue(record[pro.Name], pro.PropertyType), null); } list.Add((T)obj); } } } catch (Exception ex) { throw ex; } finally { if (rd != null && !rd.IsClosed) { rd.Close(); rd.Dispose(); } } return list; } #endregion #region 獲取列表 /// <summary> /// 獲取列表 /// </summary> public List<T> FindListBySql<T>(string sql, params SQLiteParameter[] cmdParms) where T : new() { List<T> list = new List<T>(); object obj; IDataReader rd = null; try { rd = ExecuteReader(sql, cmdParms); if (typeof(T) == typeof(int)) { while (rd.Read()) { list.Add((T)rd[0]); } } else if (typeof(T) == typeof(string)) { while (rd.Read()) { list.Add((T)rd[0]); } } else { PropertyInfo[] propertyInfoList = (typeof(T)).GetProperties(); int fcnt = rd.FieldCount; List<string> fileds = new List<string>(); for (int i = 0; i < fcnt; i++) { fileds.Add(rd.GetName(i).ToUpper()); } while (rd.Read()) { IDataRecord record = rd; obj = new T(); foreach (PropertyInfo pro in propertyInfoList) { if (!fileds.Contains(pro.Name.ToUpper()) || record[pro.Name] == DBNull.Value) { continue; } pro.SetValue(obj, record[pro.Name] == DBNull.Value ? null : getReaderValue(record[pro.Name], pro.PropertyType), null); } list.Add((T)obj); } } } catch (Exception ex) { throw ex; } finally { if (rd != null && !rd.IsClosed) { rd.Close(); rd.Dispose(); } } return list; } #endregion #region 分頁獲取列表 /// <summary> /// 分頁(任意entity,盡量少的字段) /// </summary> public PagerModel FindPageBySql<T>(string sql, string orderby, int pageSize, int currentPage) where T : new() { PagerModel pagerModel = new PagerModel(currentPage, pageSize); using (DbConnection connection = GetConnection()) { connection.Open(); IDbCommand cmd = null; StringBuilder sb = new StringBuilder(); string commandText = null; int startRow = 0; int endRow = 0; switch (m_DBType) { case "oracle": #region 分頁查詢語句 commandText = string.Format("select count(*) from ({0}) T", sql); cmd = GetCommand(commandText, connection); pagerModel.totalRows = int.Parse(cmd.ExecuteScalar().ToString()); startRow = pageSize * (currentPage - 1); endRow = startRow + pageSize; sb.Append("select * from ( select row_limit.*, rownum rownum_ from ("); sb.Append(sql); if (!string.IsNullOrWhiteSpace(orderby)) { sb.Append(" "); sb.Append(orderby); } sb.Append(" ) row_limit where rownum <= "); sb.Append(endRow); sb.Append(" ) where rownum_ >"); sb.Append(startRow); #endregion break; case "mssql": #region 分頁查詢語句 commandText = string.Format("select count(*) from ({0}) T", sql); cmd = GetCommand(commandText, connection); pagerModel.totalRows = int.Parse(cmd.ExecuteScalar().ToString()); startRow = pageSize * (currentPage - 1) + 1; endRow = startRow + pageSize - 1; sb.Append(string.Format(@" select * from (select ROW_NUMBER() over({1}) as rowNumber, t.* from ({0}) t) tempTable where rowNumber between {2} and {3} ", sql, orderby, startRow, endRow)); #endregion break; case "mysql": #region 分頁查詢語句 commandText = string.Format("select count(*) from ({0}) T", sql); cmd = GetCommand(commandText, connection); pagerModel.totalRows = int.Parse(cmd.ExecuteScalar().ToString()); startRow = pageSize * (currentPage - 1); sb.Append("select * from ("); sb.Append(sql); if (!string.IsNullOrWhiteSpace(orderby)) { sb.Append(" "); sb.Append(orderby); } sb.AppendFormat(" ) row_limit limit {0},{1}", startRow, pageSize); #endregion break; case "sqlite": #region 分頁查詢語句 commandText = string.Format("select count(*) from ({0}) T", sql); cmd = GetCommand(commandText, connection); pagerModel.totalRows = int.Parse(cmd.ExecuteScalar().ToString()); startRow = pageSize * (currentPage - 1); sb.Append(sql); if (!string.IsNullOrWhiteSpace(orderby)) { sb.Append(" "); sb.Append(orderby); } sb.AppendFormat(" limit {0} offset {1}", pageSize, startRow); #endregion break; } List<T> list = FindListBySql<T>(sb.ToString()); pagerModel.result = list; } return pagerModel; } #endregion #region 分頁獲取列表 /// <summary> /// 分頁(任意entity,盡量少的字段) /// </summary> /// <typeparam name="T"></typeparam> /// <param name="sql"></param> /// <returns></returns> public PagerModel FindPageBySql<T>(string sql, string orderby, int pageSize, int currentPage, params SQLiteParameter[] cmdParms) where T : new() { PagerModel pagerModel = new PagerModel(currentPage, pageSize); using (DbConnection connection = GetConnection()) { connection.Open(); IDbCommand cmd = null; StringBuilder sb = new StringBuilder(); string commandText = null; int startRow = 0; int endRow = 0; switch (m_DBType) { case "oracle": #region 分頁查詢語句 commandText = string.Format("select count(*) from ({0}) T", sql); cmd = GetCommand(commandText, connection); pagerModel.totalRows = int.Parse(cmd.ExecuteScalar().ToString()); startRow = pageSize * (currentPage - 1); endRow = startRow + pageSize; sb.Append("select * from ( select row_limit.*, rownum rownum_ from ("); sb.Append(sql); if (!string.IsNullOrWhiteSpace(orderby)) { sb.Append(" "); sb.Append(orderby); } sb.Append(" ) row_limit where rownum <= "); sb.Append(endRow); sb.Append(" ) where rownum_ >"); sb.Append(startRow); #endregion break; case "mssql": #region 分頁查詢語句 commandText = string.Format("select count(*) from ({0}) T", sql); cmd = GetCommand(commandText, connection); pagerModel.totalRows = int.Parse(cmd.ExecuteScalar().ToString()); startRow = pageSize * (currentPage - 1) + 1; endRow = startRow + pageSize - 1; sb.Append(string.Format(@" select * from (select ROW_NUMBER() over({1}) as rowNumber, t.* from ({0}) t) tempTable where rowNumber between {2} and {3} ", sql, orderby, startRow, endRow)); #endregion break; case "mysql": #region 分頁查詢語句 commandText = string.Format("select count(*) from ({0}) T", sql); cmd = GetCommand(commandText, connection); pagerModel.totalRows = int.Parse(cmd.ExecuteScalar().ToString()); startRow = pageSize * (currentPage - 1); sb.Append("select * from ("); sb.Append(sql); if (!string.IsNullOrWhiteSpace(orderby)) { sb.Append(" "); sb.Append(orderby); } sb.AppendFormat(" ) row_limit limit {0},{1}", startRow, pageSize); #endregion break; case "sqlite": #region 分頁查詢語句 commandText = string.Format("select count(*) from ({0}) T", sql); cmd = GetCommand(commandText, connection); pagerModel.totalRows = int.Parse(cmd.ExecuteScalar().ToString()); startRow = pageSize * (currentPage - 1); sb.Append(sql); if (!string.IsNullOrWhiteSpace(orderby)) { sb.Append(" "); sb.Append(orderby); } sb.AppendFormat(" limit {0} offset {1}", pageSize, startRow); #endregion break; } List<T> list = FindListBySql<T>(sb.ToString(), cmdParms); pagerModel.result = list; } return pagerModel; } #endregion #region 分頁獲取列表 /// <summary> /// 分頁(任意entity,盡量少的字段) /// </summary> public DataSet FindPageBySql(string sql, string orderby, int pageSize, int currentPage, out int totalCount, params SQLiteParameter[] cmdParms) { DataSet ds = null; using (DbConnection connection = GetConnection()) { connection.Open(); IDbCommand cmd = null; StringBuilder sb = new StringBuilder(); string commandText = null; int startRow = 0; int endRow = 0; totalCount = 0; switch (m_DBType) { case "oracle": #region 分頁查詢語句 commandText = string.Format("select count(*) from ({0}) T", sql); cmd = GetCommand(commandText, connection); totalCount = int.Parse(cmd.ExecuteScalar().ToString()); startRow = pageSize * (currentPage - 1); endRow = startRow + pageSize; sb.Append("select * from ( select row_limit.*, rownum rownum_ from ("); sb.Append(sql); if (!string.IsNullOrWhiteSpace(orderby)) { sb.Append(" "); sb.Append(orderby); } sb.Append(" ) row_limit where rownum <= "); sb.Append(endRow); sb.Append(" ) where rownum_ >"); sb.Append(startRow); #endregion break; case "mssql": #region 分頁查詢語句 commandText = string.Format("select count(*) from ({0}) T", sql); cmd = GetCommand(commandText, connection); totalCount = int.Parse(cmd.ExecuteScalar().ToString()); startRow = pageSize * (currentPage - 1) + 1; endRow = startRow + pageSize - 1; sb.Append(string.Format(@" select * from (select ROW_NUMBER() over({1}) as rowNumber, t.* from ({0}) t) tempTable where rowNumber between {2} and {3} ", sql, orderby, startRow, endRow)); #endregion break; case "mysql": #region 分頁查詢語句 commandText = string.Format("select count(*) from ({0}) T", sql); cmd = GetCommand(commandText, connection); totalCount = int.Parse(cmd.ExecuteScalar().ToString()); startRow = pageSize * (currentPage - 1); sb.Append("select * from ("); sb.Append(sql); if (!string.IsNullOrWhiteSpace(orderby)) { sb.Append(" "); sb.Append(orderby); } sb.AppendFormat(" ) row_limit limit {0},{1}", startRow, pageSize); #endregion break; case "sqlite": #region 分頁查詢語句 commandText = string.Format("select count(*) from ({0}) T", sql); cmd = GetCommand(commandText, connection); totalCount = int.Parse(cmd.ExecuteScalar().ToString()); startRow = pageSize * (currentPage - 1); sb.Append(sql); if (!string.IsNullOrWhiteSpace(orderby)) { sb.Append(" "); sb.Append(orderby); } sb.AppendFormat(" limit {0} offset {1}", pageSize, startRow); #endregion break; } ds = Query(sql, cmdParms); } return ds; } #endregion #region getReaderValue 轉換數據 /// <summary> /// 轉換數據 /// </summary> private Object getReaderValue(Object rdValue, Type ptype) { if (ptype == typeof(double)) return Convert.ToDouble(rdValue); if (ptype == typeof(decimal)) return Convert.ToDecimal(rdValue); if (ptype == typeof(int)) return Convert.ToInt32(rdValue); if (ptype == typeof(long)) return Convert.ToInt64(rdValue); if (ptype == typeof(DateTime)) return Convert.ToDateTime(rdValue); if (ptype == typeof(Nullable<double>)) return Convert.ToDouble(rdValue); if (ptype == typeof(Nullable<decimal>)) return Convert.ToDecimal(rdValue); if (ptype == typeof(Nullable<int>)) return Convert.ToInt32(rdValue); if (ptype == typeof(Nullable<long>)) return Convert.ToInt64(rdValue); if (ptype == typeof(Nullable<DateTime>)) return Convert.ToDateTime(rdValue); return rdValue; } #endregion #region 獲取主鍵名稱 /// <summary> /// 獲取主鍵名稱 /// </summary> public string GetIdName(Type type) { PropertyInfo[] propertyInfoList = GetEntityProperties(type); foreach (PropertyInfo propertyInfo in propertyInfoList) { if (propertyInfo.GetCustomAttributes(typeof(IsIdAttribute), false).Length > 0) { return propertyInfo.Name; } } return "Id"; } #endregion #region 獲取主鍵值 /// <summary> /// 獲取主鍵名稱 /// </summary> public object GetIdVal(object val) { string idName = GetIdName(val.GetType()); if (!string.IsNullOrWhiteSpace(idName)) { return val.GetType().GetProperty(idName).GetValue(val, null); } return 0; } #endregion #region 獲取實體類屬性 /// <summary> /// 獲取實體類屬性 /// </summary> private PropertyInfo[] GetEntityProperties(Type type) { List<PropertyInfo> result = new List<PropertyInfo>(); PropertyInfo[] propertyInfoList = type.GetProperties(); foreach (PropertyInfo propertyInfo in propertyInfoList) { if (propertyInfo.GetCustomAttributes(typeof(EdmRelationshipNavigationPropertyAttribute), false).Length == 0 && propertyInfo.GetCustomAttributes(typeof(BrowsableAttribute), false).Length == 0) { result.Add(propertyInfo); } } return result.ToArray(); } #endregion #region 獲取基類 /// <summary> /// 獲取基類 /// </summary> public Type GetBaseType(Type type) { while (type.BaseType != null && type.BaseType.Name != typeof(Object).Name) { type = type.BaseType; } return type; } #endregion #endregion #region 事務 #region 開始事務 /// <summary> /// 開始事務 /// </summary> public static void BeginTransaction() { DbConnection conn = GetConnection(); if (conn.State != ConnectionState.Open) conn.Open(); m_Tran = conn.BeginTransaction(); } #endregion #region 提交事務 /// <summary> /// 提交事務 /// </summary> public static void CommitTransaction() { DbConnection conn = m_Tran.Connection; try { m_Tran.Commit(); } catch (Exception ex) { m_Tran.Rollback(); } finally { if (conn.State == ConnectionState.Open) conn.Close(); m_Tran.Dispose(); m_Tran = null; } } #endregion #region 回滾事務(出錯時調用該方法回滾) /// <summary> /// 回滾事務(出錯時調用該方法回滾) /// </summary> public static void RollbackTransaction() { DbConnection conn = m_Tran.Connection; m_Tran.Rollback(); if (conn.State == ConnectionState.Open) conn.Close(); } #endregion #endregion } } View Code
如何使用:
添加:
/// <summary> /// 添加 /// </summary> public void Insert(object obj) { dbHelper.Insert(obj); } View Code修改:
/// <summary> /// 修改 /// </summary> public void Update(object obj) { dbHelper.Update(obj); } View Code根據ID刪除:
/// <summary> /// 刪除 /// </summary> public void Del(int id) { dbHelper.Delete<BS_Template>(id); } View Code根據ID批量刪除:
/// <summary> /// 刪除 /// </summary> public void BatchDelete(string ids) { dbHelper.BatchDelete<BS_Template>(ids); } View Code根據條件刪除:
/// <summary> /// 刪除 /// </summary> public void Delete(string conditions) { dbHelper.Delete<BS_Template>(conditions); } View Code獲取最大ID(當然,ID一般采用自增,對於並發量極少的系統,或單機系統,為了省事,可以這樣做):
/// <summary> /// GetMaxId /// </summary> public int GetMaxId() { return dbHelper.GetMaxID<BS_Template>("id"); } View Code根據條件查詢實體:
public BS_Template Get(string typeCode, Enums.TemplateType templateType) { StringBuilder sql = new StringBuilder(string.Format(@" select * from BS_Template where typeCode='{0}' and type='{1}'", typeCode, (int)templateType)); return dbHelper.FindBySql<BS_Template>(sql.ToString()); } public BS_Template Get2(string templateId, Enums.TemplateType templateType) { StringBuilder sql = new StringBuilder(string.Format(@" select * from BS_Template where id='{0}' and type='{1}'", templateId, (int)templateType)); return dbHelper.FindBySql<BS_Template>(sql.ToString()); } View Code根據ID查詢實體:
public BS_Test Get(string id) { return dbHelper.FindById<BS_Test>(id); } View Code查詢列表:
/// <summary> /// 查詢列表 /// </summary> public List<BS_Test> GetList(string name) { StringBuilder sql = new StringBuilder(string.Format(@" select * from BS_Test t where 1=1 ")); if (!string.IsNullOrWhiteSpace(name)) { sql.AppendFormat(" and t.name like '%{0}%'", name); } return dbHelper.FindListBySql<BS_Test>(sql.ToString()); } View Code分頁查詢列表:
/// <summary> /// 分頁獲取模板集合 /// </summary> public List<BS_Template> GetList(ref PagerModel pager, string noticeType, string coreType, string name, Enums.TemplateType templateType) { StringBuilder sql = new StringBuilder(string.Format(@" select * from BS_Template t where 1=1 ")); if (!string.IsNullOrWhiteSpace(noticeType)) { sql.AppendFormat(" and nt.name like '%{0}%'", noticeType); } if (!string.IsNullOrWhiteSpace(coreType)) { sql.AppendFormat(" and ct.name like '%{0}%'", coreType); } if (!string.IsNullOrWhiteSpace(name)) { sql.AppendFormat(" and t.name like '%{0}%'", name); } sql.AppendFormat(" and t.type = '{0}'", (int)templateType); string orderby = "order by cast(id as int)"; pager = dbHelper.FindPageBySql<BS_Template>(sql.ToString(), orderby, pager.rows, pager.page); return pager.result as List<BS_Template>; } View Code完整DAL:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using DBUtil; using Models; namespace DAL { /// <summary> /// 模板 /// </summary> public class TemplateDal { #region 變量 private DBHelper dbHelper = new DBHelper(); #endregion #region 分頁獲取模板集合 /// <summary> /// 分頁獲取模板集合 /// </summary> public List<BS_Template> GetList(ref PagerModel pager, string noticeType, string coreType, string name, Enums.TemplateType templateType) { StringBuilder sql = new StringBuilder(string.Format(@" select * from BS_Template t where 1=1 ")); if (!string.IsNullOrWhiteSpace(noticeType)) { sql.AppendFormat(" and nt.name like '%{0}%'", noticeType); } if (!string.IsNullOrWhiteSpace(coreType)) { sql.AppendFormat(" and ct.name like '%{0}%'", coreType); } if (!string.IsNullOrWhiteSpace(name)) { sql.AppendFormat(" and t.name like '%{0}%'", name); } sql.AppendFormat(" and t.type = '{0}'", (int)templateType); string orderby = "order by cast(id as int)"; pager = dbHelper.FindPageBySql<BS_Template>(sql.ToString(), orderby, pager.rows, pager.page); return pager.result as List<BS_Template>; } #endregion #region 獲取字段關聯模板集合 /// <summary> /// 獲取字段關聯模板集合 /// </summary> public List<BS_Template> GetList(string fieldId) { StringBuilder sql = new StringBuilder(string.Format(@" select * from BS_Template t left join BS_TplFieldRelation r on r.templateId=t.id left join BS_TplField f on f.id=r.fieldId where f.id='{0}'", fieldId)); return dbHelper.FindListBySql<BS_Template>(sql.ToString()); } #endregion #region 獲取 public BS_Template Get(string typeCode, Enums.TemplateType templateType) { StringBuilder sql = new StringBuilder(string.Format(@" select * from BS_Template where typeCode='{0}' and type='{1}'", typeCode, (int)templateType)); return dbHelper.FindBySql<BS_Template>(sql.ToString()); } public BS_Template Get2(string templateId, Enums.TemplateType templateType) { StringBuilder sql = new StringBuilder(string.Format(@" select * from BS_Template where id='{0}' and type='{1}'", templateId, (int)templateType)); return dbHelper.FindBySql<BS_Template>(sql.ToString()); } #endregion #region GetMaxId /// <summary> /// GetMaxId /// </summary> public int GetMaxId() { return dbHelper.GetMaxID<BS_Template>("id"); } #endregion #region 添加 /// <summary> /// 添加 /// </summary> public void Insert(object obj) { dbHelper.Insert(obj); } #endregion #region 修改 /// <summary> /// 修改 /// </summary> public void Update(object obj) { dbHelper.Update(obj); } #endregion #region 刪除 /// <summary> /// 刪除 /// </summary> public void Del(int id) { dbHelper.Delete<BS_Template>(id); } /// <summary> /// 刪除 /// </summary> public void BatchDelete(string ids) { dbHelper.BatchDelete<BS_Template>(ids); } /// <summary> /// 刪除 /// </summary> public void Delete(string conditions) { dbHelper.Delete<BS_Template>(conditions); } #endregion } } View Code查詢sql書寫規范:
SQL不能寫的亂七八糟,該換行換行,該對齊對齊,例:
/// <summary> /// 分頁獲取模板集合 /// </summary> public List<BS_Template> GetList(ref PagerModel pager, string noticeType, string coreType, string name, Enums.TemplateType templateType) { StringBuilder sql = new StringBuilder(string.Format(@" select * from BS_Template t where 1=1 ")); if (!string.IsNullOrWhiteSpace(noticeType)) { sql.AppendFormat(" and nt.name like '%{0}%'", noticeType); } if (!string.IsNullOrWhiteSpace(coreType)) { sql.AppendFormat(" and ct.name like '%{0}%'", coreType); } if (!string.IsNullOrWhiteSpace(name)) { sql.AppendFormat(" and t.name like '%{0}%'", name); } sql.AppendFormat(" and t.type = '{0}'", (int)templateType); string orderby = "order by cast(id as int)"; pager = dbHelper.FindPageBySql<BS_Template>(sql.ToString(), orderby, pager.rows, pager.page); return pager.result as List<BS_Template>; } View Codeselect換行,from換行,join換行,where換行,and換行。
數據庫事務:
try { DBHelper.BeginTransaction(); BS_Template model = new BS_Template(); model.id = m_TemplateDal.GetMaxId().ToString(); model.code = k.ToString("0000"); model.name = "測試" + k.ToString(); model.remarks = "測試" + k.ToString(); model.type = ((int)Enums.TemplateType.Notice).ToString(); m_TemplateDal.Insert(model); //throw new Exception("a"); BS_Test test = new BS_Test(); test.id = m_TestDal.GetMaxId().ToString(); test.code = "測試" + k.ToString(); test.name = "測試" + k.ToString(); test.remarks = "測試" + k.ToString(); m_TestDal.Insert(test); DBHelper.CommitTransaction(); MessageBox.Show("成功"); } catch (Exception ex) { DBHelper.RollbackTransaction(); MessageBox.Show(ex.Message); } View Code
代碼下載:http://files.cnblogs.com/files/s0611163/DBHelperDemo.zip
Model生成器下載:http://files.cnblogs.com/files/s0611163/Model%E7%94%9F%E6%88%90%E5%99%A8.zip