前述:
第一次發表文章,不過是對數據庫簡單的封裝,主要是闡述下思路。那么在上篇文章,在大家的指導下和提出意見,並自己對代碼進行了思考。在這兩天我重構了新的框架,我覺得我寫的可以稱得上框架,為什么?請大家往下看。不過在項目中沒有很多注釋。筆者除了課余學習時候,大部分時間在完成學校的功課,沒有許多時間,所以也就偷下懶,請大家體諒。
這次框架分為幾個部分:拼接數據庫語句、數據庫執行、數據庫連接控制、異常類、用戶使用的DbHelper。等下我回用文字和圖還分析這個部分。經過重構后,類增多了,而且能夠極大的支持開閉原則,我應該說就是與實際數據庫無關,而且在上層使用中,不需要在引用system.Data.SqlClient這樣實際訪問的東西。雖然筆者只寫了sql server的實例,但是如果擴展其他的數據庫,也無需大規模的修改舊的代碼,並且使用參數,能夠防止注入攻擊,支持事務。
好,先看怎么使用框架。
DbHelper helper = new DbHelper(); helper.createConnection("MyConnection","Data Source=CN-20161106HMJI;Initial Catalog=ShopInfo;Integrated Security=True",DbType.SQL); PlaceInfo model = helper.ExcuteString(o => o.From("PlaceInfo").Select().AndWhere("SAddNo", 1)).ToModel<PlaceInfo>(); Console.Read();
上面是使用的一個例子,創建連接字符串,然后查詢獲取實例,已經沒有打開數據庫,或者是command的語句,使用起來是否十分簡單,上面這句運行沒有問題的,因為框架靈活度太大,測試的話不能所有都包含,這也是沒辦法,接下來跟着文章,一步步分析。
上次說,鏈式編程很好用,所以這次同樣是鏈式編程,但這次更為強大。大家知道,dal的鏈式編程,主要是得到數據,而得到數據無非是對數據庫查詢語言進行封裝。所以,在框架上,我封裝了一個拼接語句的類,里面包含了我認為比較常用的數據庫語句,支持order by。還有最強大的是,能夠支持嵌套查詢!也就是封裝的sql語句可以是
select * from tableName where Id in(select id from tablename where ...)...這樣子的。使用起來十分的方便。而且還有排序order by,等,可以在使用這套框架封裝更使用的方法。
第二個新增的是連接控制,這個是這套框架的關鍵,因為框架不能占用內存,所以無論在拼接查詢語句,還是在執行部分,都沒有對數據庫創建的語句,而是采用注入式,通過連接控制類,創建好數據庫連接后,注入到所需要的部分中。而且這里控制了最耗性能的反射,對模型中的屬性進行反射,都是耗時間,所以這里設置了緩存,對已經創建過對象的保存在這里,在拼接數據庫語句或者是執行階段需要用到,注入到其中,就可以省下時間。
第三個增加的是異常類,不過我封裝的比較簡單,里面就一個可重載的方法,這個是用來發生異常時候,用戶能夠自己設置發生錯誤之后應該做什么(比如保存到日志)而定的。
最后一個新增的是釋放資源,因為對數據庫連接,數據庫連接數目比較少,但是command的數目在一般項目可就不是這樣。可能大家為了方便,所以使用的時候盡情的new這樣,那在我的框架設置了一個集合,專門存放command的,在用完后能夠釋放資源。因為考慮到在事務執行時候不能夠對comand進行釋放,所以在釋放時候還做了判斷。把有事務的command放到在事務執行后釋放。
看完上邊的功能,是不是覺得十分強大,因為這個框架理解和實現起來都不容易,所以筆者盡可能的讓大家明白,知道我是怎么一步步完成的。
現在進入正題,先看下簡單的結構圖,看上去比較簡單,不是我不會繪圖,我在完成其他項目時候,都有完整的文檔和圖,因為現在沒有太多時間,而且用軟件畫實在太慢了,所以大家將就的看吧。
上圖就是我框架的結構圖。箭頭代表關聯,從下到上,代表底層到用戶使用的層次。框架是支持對數據庫的擴展,上邊三個部分寫繼承抽象類就是如此,因為這幾個其實就是實際數據庫會使用到,所以使用工廠模式,這樣就能夠擴展其他了。
好了,看完圖,就開始講解代碼。
我第一步是從數據庫拼接語句開始做的,因為這個雖然還不算底層,但是相對於其他可以獨立,那么看下這一跪部分的類:
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Dal { public interface IDbCode { /// <summary> /// 數據庫執行表、視圖、存儲過程等對象 /// </summary> /// <param name="Object">名稱</param> /// <returns></returns> IDbCode From(object Object); /// <summary> /// 查詢 /// </summary> /// <param name="Fields">查詢的字段</param> /// <returns></returns> IDbCode Select(string Fields = "*"); /// <summary> /// 刪除 /// </summary> /// <returns></returns> IDbCode Delete(); /// <summary> /// 更新 /// </summary> /// <param name="model">更新對象</param> /// <param name="Fields">更新字段</param> /// <returns></returns> IDbCode Update(object model,string Fields = ""); /// <summary> /// 插入 /// </summary> /// <param name="model">插入對象</param> /// <param name="Fields">插入字段</param> /// <returns></returns> IDbCode Insert(object model,string Fields = ""); /// <summary> /// 與條件 /// </summary> /// <param name="Where">條件字符串</param> /// <returns></returns> IDbCode AndWhere(string Where); /// <summary> /// 與條件 /// </summary> /// <param name="Field">字段</param> /// <param name="Value">值</param> /// <returns></returns> IDbCode AndWhere(string Field,object Value); /// <summary> /// 與條件 /// </summary> /// <param name="Field">條件字段</param> /// <param name="Select">嵌套查詢條件委托</param> /// <returns></returns> IDbCode AndWhere(string Field, Func<IDbCode, string> Select); /// <summary> /// 與條件 /// </summary> /// <typeparam name="T">值的類型</typeparam> /// <param name="Field">條件字段</param> /// <param name="Values">值</param> /// <returns></returns> IDbCode AndWhere<T>(string Field,List<T> Values); /// <summary> /// 或條件 /// </summary> /// <param name="Where">條件字符串</param> /// <returns></returns> IDbCode OrWhere(string Where); /// <summary> /// 或條件 /// </summary> /// <param name="Field">條件字段</param> /// <param name="Value">值</param> /// <returns></returns> IDbCode OrWhere(string Field, object Value); /// <summary> /// 或條件 /// </summary> /// <param name="Field">條件字段</param> /// <param name="Select">嵌套條件</param> /// <returns></returns> IDbCode OrWhere(string Field, Func<IDbCode, string> Select); /// <summary> /// 或條件 /// </summary> /// <typeparam name="T">值類型</typeparam> /// <param name="Field">條件字段</param> /// <param name="Values">值</param> /// <returns></returns> IDbCode OrWhere<T>(string Field, List<T> Values); /// <summary> /// Top 語句 /// </summary> /// <param name="topCount"></param> /// <returns></returns> IDbCode Top(int topCount); /// <summary> /// 排序從小到大 /// </summary> /// <param name="Field">排序字段</param> /// <returns></returns> IDbCode OrderByAsc(string Field); /// <summary> /// 排序從大到小 /// </summary> /// <param name="Field">排序字段</param> /// <returns></returns> IDbCode OrderByDesc(string Field); /// <summary> /// 多表查詢時候必須加的條件 /// </summary> /// <param name="Fields">在兩張表中的相同字段</param> /// <returns></returns> IDbCode ForMulTable(string Fields); string ToString(); /// <summary> /// 清空緩存 /// </summary> /// <returns></returns> IDbCode Clear(); IDbCode CreateCode(string sql); object Paras { get; } void Dispose(); } }
繼承它的類:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Data; using System.Data.SqlClient; using System.Reflection; namespace Dal { public class SQLCode :IDbCode { string Object; StringBuilder ExcuteString = new StringBuilder(); List<SqlParameter> paras; Dictionary<string, List<PropertyInfo>> pro; static string[] s = { "select", "delect", "update", "insert" }; public SQLCode() { paras = new List<SqlParameter>(); } public SQLCode(Dictionary<string, List<PropertyInfo>> pro) { paras = new List<SqlParameter>(); this.pro = pro; } public SQLCode(List<SqlParameter> paras, Dictionary<string, List<PropertyInfo>> pro) { this.paras = paras; this.pro = pro; } public IDbCode From(object Object) { Type t = Object.GetType(); if(t.Name.ToLower().Equals("string")) { this.Object = Object.ToString(); }else { this.Object = t.Name; } return this; } public IDbCode Select(string Fields = "*") { if (this.Object.Length <= 0) return this; if (!Check(0)) return this; ExcuteString.AppendLine("select " + Fields +" from "+ this.Object); ExcuteString.AppendLine(" where 1 = 1 "); return this; } bool Check(int Type) { int flag = 0; string b = ExcuteString.ToString(); for (int i = 0; i < s.Length; i++) if(i!=Type) flag += b.Contains(s[i]) ? 1 : 0; return flag == 0; } public IDbCode Delete() { if (Object.Length <= 0) return this; if (!Check(1)) return this; ExcuteString.AppendLine("delete " + this.Object); ExcuteString.AppendLine(" where 1 = 1 "); return this; } public IDbCode Update(object model, string Fields = "") { if (this.Object.Length <= 0) return this; if (!Check(2)) return this; Type t = model.GetType(); if (t.Name != Object) return this; ExcuteString.AppendLine("update "+this.Object +" set "); List<PropertyInfo> p; if(pro.ContainsKey(t.Name)) { p = pro[t.Name]; }else { p = t.GetProperties().ToList(); pro.Add(t.Name, p); } string f = ""; if(Fields.Length==0) { p.ForEach(o => { f += o.Name + " = @" + o.Name; paras.Add(new SqlParameter(o.Name, o.GetValue(model, null))); }); }else { string[] a = Fields.Split(','); p.ForEach(o => { if (a.Contains(o.Name)) { f += o.Name + " = @" + o.Name + ","; paras.Add(new SqlParameter(o.Name, o.GetValue(model, null))); } }); } ExcuteString.AppendLine(f); ExcuteString.AppendLine("where 1 = 1"); return this; } public IDbCode Insert(object model, string Fields = "") { if (this.Object.Length <= 0) return this; if (!Check(3)) return this; Type t = model.GetType(); if (t.Name != Object) return this; ExcuteString.AppendLine("insert " + this.Object); List<PropertyInfo> p; if (pro.ContainsKey(t.Name)) { p = pro[t.Name]; } else { p = t.GetProperties().ToList(); pro.Add(t.Name, p); } string f = "( "; string f1 = "values( "; if (Fields.Length == 0) { p.ForEach(o => { f += o.Name+","; paras.Add(new SqlParameter(o.Name, o.GetValue(model, null))); f1 += "@" + o.Name + ","; }); } else { string[] a = Fields.Split(','); p.ForEach(o => { if (a.Contains(o.Name)) { f += o.Name + ","; paras.Add(new SqlParameter(o.Name, o.GetValue(model, null))); f1 += "@" + o.Name + ","; } }); } f = f.Remove(f.LastIndexOf(','), 1) + " ) "; f1 = f1.Remove(f1.LastIndexOf(','), 1) + " ) "; ExcuteString.AppendLine(f); ExcuteString.AppendLine(f1); return this; } public IDbCode AndWhere(string Where) { ExcuteString.AppendLine(" and " + Where); return this; } public IDbCode AndWhere(string Field, object Value) { ExcuteString.AppendLine(" and " + Field + " = @" + Field); paras.Add(new SqlParameter(Field, Value)); return this; } public IDbCode AndWhere(string Field, Func<IDbCode, string> Select) { ExcuteString.AppendLine(" and " + Field + " in " + Select(new SQLCode(this.paras,this.pro))); return this; } public IDbCode AndWhere<T>(string Field, List<T> Values) { string value = "("; Values.ForEach(o => { value += o + ","; }); ExcuteString.AppendLine(" and " + Field + " in " + value.Remove(value.LastIndexOf(','), 1) + ")"); return this; } public IDbCode OrWhere(string Where) { ExcuteString.AppendLine(" or " + Where); return this; } public IDbCode OrWhere(string Field, object Value) { ExcuteString.AppendLine(" or " + Field + " = @" + Field); paras.Add(new SqlParameter(Field, Value)); return this; } public IDbCode OrWhere(string Field, Func<IDbCode, string> Select) { ExcuteString.AppendLine(" or " + Field + " in " + Select(new SQLCode(this.paras,this.pro))); return this; } public IDbCode OrWhere<T>(string Field, List<T> Values) { string value = "("; Values.ForEach(o => { value += o + ","; }); ExcuteString.AppendLine(" or " + Field + " in " + value.Remove(value.LastIndexOf(','), 1) + ")"); return this; } public IDbCode Top(int topCount) { if (!ExcuteString.ToString().Contains(s[0])) return this; ExcuteString.Replace("select", "select top " + topCount +" "); return this; } bool CheckHasOrderBy() { return this.ExcuteString.ToString().Contains("order by"); } public IDbCode OrderByAsc(string Field) { if (CheckHasOrderBy()) ExcuteString.AppendLine("," + Field + " asc"); else ExcuteString.AppendLine(" order by " + Field+" asc"); return this; } public IDbCode OrderByDesc(string Field) { if (CheckHasOrderBy()) ExcuteString.AppendLine("," + Field + " desc"); else ExcuteString.AppendLine(" order by " + Field + " desc"); return this; } public IDbCode ForMulTable(string Fields) { List<string> tables = this.Object.Split(',').ToList(); Fields.Split(',').ToList().ForEach(o => { for (int i = 0; i < tables.Count - 1; i++) { ExcuteString.AppendLine(" and " + tables[i] + "." + o + " = " + tables[i + 1] + "." + o); } }); return this; } public override string ToString() { return this.ExcuteString.ToString(); } public IDbCode Clear() { pro.Clear(); return this; } public IDbCode CreateCode(string sql) { ExcuteString.AppendLine(sql); return this; } public object Paras { get { return this.paras; } } public void Dispose() { this.pro = null; } } }
如果有看過上次的文章,那么就知道這里部分方法用到反射,獲取其中的屬性來拼寫語句。沒什么難的,大家看到里面有許多的if條件,是我避免在鏈式組合時候,用戶隨便亂時候而設置的。這部分都是對字符串處理。
第二部分是執行語句,這個相信大家寫多了,先給代碼:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Data; using System.Data.SqlClient; namespace Dal { public interface IDbExcute { T ToModel<T>(IDbCode code, CommandType type = CommandType.Text) where T : class,new(); List<T> ToList<T>(IDbCode code,CommandType type = CommandType.Text) where T : class,new(); object ToResult(IDbCode code, CommandType type = CommandType.Text); int ExcuteResult(IDbCode code, CommandType type = CommandType.Text); DataTable ToDataTable(IDbCode code, CommandType type = CommandType.Text); DataSet ToDataSet(IDbCode code, CommandType type = CommandType.Text); void OpenConnection(); void CloseConnection(); void Dispose(object tran); void BeginTransation(string Name); void Commit(); void RollBack(); } }
上面就是支持整個框架的執行方法
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Data; using System.Data.SqlClient; using System.Reflection; namespace Dal { public class SQLExcute : IDbExcute { SqlConnection conn; Dictionary<string, List<PropertyInfo>> pro; Dictionary<string, SqlCommand> command; SqlTransaction tran = null; public SQLExcute(SqlConnection conn, Dictionary<string, List<PropertyInfo>> pro) { this.conn = conn; this.pro = pro; command = new Dictionary<string, SqlCommand>(); } public List<T> ToList<T>(IDbCode code,CommandType type = CommandType.Text) where T:class,new() { List<T> list = new List<T>(); string name = DateTime.Now.ToString(); command.Add(name, new SqlCommand()); SqlCommand com = command[name]; com.Connection = conn; com.CommandText = code.ToString(); com.CommandType = type; setCommand(com, (List<SqlParameter>)code.Paras); Type t = typeof(T); List<PropertyInfo> pros; if(pro.ContainsKey(t.Name)) { pros = pro[t.Name]; }else { pros = t.GetProperties().ToList(); pro.Add(t.Name, pros); } try { this.OpenConnection(); using (SqlDataReader reader = com.ExecuteReader()) { while(reader.Read()) { T model = new T(); pros.ForEach(o => { if(ReaderExists(reader,o.Name)) { o.SetValue(model, reader[o.Name], null); } }); list.Add(model); } } } catch (Exception ex) { throw ex; } finally { this.Dispose(name); this.CloseConnection(); } return list; } public bool ReaderExists(SqlDataReader reader, string columnName) { //reader.GetSchemaTable().DefaultView.RowFilter = "ColumnName= '" + columnName + "'"; //return (reader.GetSchemaTable().DefaultView.Count > 0); return reader.GetSchemaTable().Select("ColumnName='" + columnName + "'").Length > 0; } public void Dispose(string name) { if(command.ContainsKey(name)) { SqlCommand com = command[name]; command.Remove(name); com.Dispose(); } if (command.Count <= 0) this.CloseConnection(); } public void Dispose(object tran) { List<string> list = command.Keys.ToList(); list.ForEach(o => { if(command[o].Transaction!=null&&command[o].Transaction==(SqlTransaction)tran) { this.Dispose(o); } }); } public object ToResult(IDbCode code, CommandType type = CommandType.Text) { string name = DateTime.Now.ToString(); command.Add(name, new SqlCommand()); SqlCommand com = command[name]; com.Connection = conn; com.CommandText = code.ToString(); com.CommandType = type; setCommand(com, (List<SqlParameter>)code.Paras); object result =null; try { this.OpenConnection(); result = com.ExecuteScalar(); } catch (Exception ex) { DoException(); throw ex; }finally { this.Dispose(name); this.CloseConnection(); } return result; } private void DoException() { new DbException().Done(); } public int ExcuteResult(IDbCode code, CommandType type = CommandType.Text) { string name = DateTime.Now.ToString(); command.Add(name, new SqlCommand()); SqlCommand com = command[name]; com.Connection = conn; com.CommandText = code.ToString(); com.CommandType = type; setCommand(com, (List<SqlParameter>)code.Paras); int result = 0; try { this.OpenConnection(); if (tran != null) com.Transaction = (SqlTransaction)tran; result = com.ExecuteNonQuery(); } catch (Exception ex) { DoException(); throw ex; } finally { if (tran == null) Dispose(name); this.CloseConnection(); } return result; } public System.Data.DataTable ToDataTable(IDbCode code, CommandType type = CommandType.Text) { string name = DateTime.Now.ToString(); command.Add(name, new SqlCommand()); SqlCommand com = command[name]; com.Connection = conn; com.CommandText = code.ToString(); com.CommandType = type; setCommand(com, (List<SqlParameter>)code.Paras); DataTable dt = new DataTable(); try { using(SqlDataAdapter adapter = new SqlDataAdapter(com)) { adapter.Fill(dt); } } catch (Exception ex) { DoException(); throw ex; }finally { Dispose(name); } return dt; } public void setCommand(SqlCommand com,List<SqlParameter> paras) { paras.ForEach(o => { com.Parameters.Add(o); }); } public System.Data.DataSet ToDataSet(IDbCode code, CommandType type = CommandType.Text) { string name = DateTime.Now.ToString(); command.Add(name, new SqlCommand()); SqlCommand com = command[name]; com.Connection = conn; com.CommandText = code.ToString(); com.CommandType = type; setCommand(com, (List<SqlParameter>)code.Paras); DataSet dt = new DataSet(); try { using (SqlDataAdapter adapter = new SqlDataAdapter(com)) { adapter.Fill(dt); } } catch (Exception ex) { DoException(); throw ex; } finally { Dispose(name); } return dt; } public T ToModel<T>(IDbCode code, CommandType type = CommandType.Text) where T : class,new() { string name = DateTime.Now.ToString(); command.Add(name, new SqlCommand()); SqlCommand com = command[name]; com.Connection = conn; com.CommandText = code.ToString(); com.CommandType = type; setCommand(com, (List<SqlParameter>)code.Paras); Type t = typeof(T); List<PropertyInfo> p = null; if(pro.ContainsKey(t.Name)) { p = pro[t.Name]; }else { p = t.GetProperties().ToList(); pro.Add(t.Name, p); } T model = new T(); try { this.OpenConnection(); using(SqlDataReader reader = com.ExecuteReader()) { if(reader.Read()) { p.ForEach(o => { if(ReaderExists(reader,o.Name)) { o.SetValue(model, reader[o.Name], null); } }); } } } catch (Exception ex) { DoException(); throw ex; } finally { Dispose(name); this.CloseConnection(); } return model; } public void OpenConnection() { if (this.conn.State != ConnectionState.Open) this.conn.Open(); } public void CloseConnection() { command.Values.ToList().ForEach(o => { if (o.Transaction != null) return; }); if (this.conn.State != ConnectionState.Closed) this.conn.Close(); } public void BeginTransation(string Name) { tran = conn.BeginTransaction(Name); } public void Commit() { tran.Commit(); Dispose(tran); tran = null; } public void RollBack() { tran.Rollback(); Dispose(tran); tran = null; } } }
具體類中,主要設計了最重要的執行方法外,還像剛開始所述,設置了List,就是用來存放command對象,在執行完成時候時候它會自己釋放。跟這個類配合使用的是異常類:
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Dal { public class DbException { public virtual void Done() { } } }
只有短短幾句話,這就是用於使用者想發生異常想它干什么而設置的。
其實封裝到這里,整個框架的支持已經形成,但是用戶不能直接操作底層,而且還需要怎么對數據庫進行實例,所以還要對上進行封裝,下一步,往上走,數據庫實例部分。
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Dal { public interface IDbInstance { /// <summary> /// 數據庫名稱 /// </summary> string Name { get; } /// <summary> /// 獲取執行語句類 /// </summary> IDbExcute Excute { get; } /// <summary> /// 獲取連接字符串 /// </summary> string ConnectionString { get; } /// <summary> /// 開啟事務 /// </summary> /// <param name="TranName">事務名稱</param> /// <returns></returns> object getTransation(string TranName); /// <summary> /// 獲取拼寫字符串類 /// </summary> IDbCode Code { get; } } }
實現它的具體類包含所有的底層的操作,其實就是可以說是一個數據庫實例了,創建一個就相當於一個數據庫。里面將上邊封裝的類都在這里使用。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Data; using System.Data.SqlClient; using System.Reflection; namespace Dal { public class SQLInstance :IDbInstance { private SqlConnection conn; private IDbExcute excute; Dictionary<string, List<PropertyInfo>> pro; private string name; private string connectionString; private SqlTransaction tran = null; public SQLInstance(string Name,Dictionary<string,List<PropertyInfo>> pro, string ConnectionString) { this.name = Name; this.connectionString = ConnectionString; conn = new SqlConnection(ConnectionString); this.pro = pro; excute = new SQLExcute(conn,pro); } public string Name { get { return this.name; } } public IDbExcute Excute { get { return this.excute; } } public string ConnectionString { get { return this.connectionString; } } public object getTransation(string TranName) { return this.conn.BeginTransaction(TranName); } public IDbCode Code { get { return new SQLCode(pro); } } } }
接下來是控制連接的類:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Reflection; namespace Dal { public class DbControl { //數據庫服務 private static Dictionary<string, IDbInstance> Server = new Dictionary<string, IDbInstance>(); //存放緩存 private static Dictionary<string, List<PropertyInfo>> pro = new Dictionary<string, List<PropertyInfo>>(); private static DbControl control = new DbControl(); public static DbControl getInstance() { return control; } private DbControl() { } public IDbInstance createInstance(string Name,string ConnectionString,string type) { string nspace = typeof(IDbInstance).Namespace; Type t = Type.GetType(nspace + "." + type); object obj = Activator.CreateInstance(t, new object[] { Name, pro, ConnectionString }); IDbInstance instance = obj as IDbInstance; Server.Add(Name, instance); return instance; } public IDbInstance this[string Name] { get { if (Server.ContainsKey(Name)) return Server[Name]; else return null; } } } }
這里算是頂層的類,最主要就是存放數據庫和緩存對象。也許會好奇如果存放數據庫,還可以理解,但是放着模型對象的緩存,這是為什么?因為在字符連接,還有具體執行數據庫語句時候都會使用到。而且,不僅這個數據庫,別的數據庫也會使用到,雖然在一個大項目可能用多個數據庫,但是他們使用到項目里的模型是一致的吧,因此,將緩存設置在這里,最好不過。而且整個框架只有這一份,其他地方注入使用,就不會耗內存了。
最后就是用戶使用的部分,這部分已經屏蔽掉許多底層的部分,只留下通用方法。這些都已經封裝好了,直接在這里調用就可以。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Data; namespace Dal { public class DbHelper { private IDbInstance instance; private string Name; private DbControl control; private IDbCode Code; public DbHelper() { control = DbControl.getInstance(); } public DbHelper createConnection(string Name, string ConnectionString, string type) { this.Name = Name; instance = control.createInstance(Name, ConnectionString, type); return this; } public DbHelper ExcuteString(Func<IDbCode,IDbCode> Fun) { Code = Fun(this.instance.Code); return this; } public DbHelper createTransation(string Name) { this.instance.Excute.BeginTransation(Name); return this; } public DbHelper Rollback() { this.instance.Excute.RollBack(); return this; } public DbHelper Commit() { this.instance.Excute.Commit(); return this; } public T ToModel<T>(CommandType Type = CommandType.Text) where T:class,new() { if (this.Code == null) return null; return this.instance.Excute.ToModel<T>(this.Code,Type); } List<T> ToList<T>(CommandType Type = CommandType.Text) where T:class,new() { if (this.Code == null) return null; return this.instance.Excute.ToList<T>(this.Code, Type); } object ToResult(CommandType Type = CommandType.Text) { if (this.Code == null) return null; return this.instance.Excute.ToResult(this.Code, Type); } int ExcuteResult(CommandType Type = CommandType.Text) { if (this.Code == null) return -1; return this.instance.Excute.ExcuteResult(this.Code, Type); } DataTable ToDataTable(CommandType Type = CommandType.Text) { if (this.Code == null) return null; return this.instance.Excute.ToDataTable(this.Code, Type); } DataSet ToDataSet(CommandType Type = CommandType.Text) { if (this.Code == null) return null; return this.instance.Excute.ToDataSet(this.Code, Type); } } }
結束:快要熄燈了,沒辦法在寫文章。如果大家對框架有什么不明白,可以在下面評論區問我。這就是更新之后的框架,我覺得還是蠻好用的,雖然還沒經過嚴密的檢測。有什么問題,大家也可以指導下,我也在學習中~