C# .NET更智能的數據庫操作的封裝完整版(重構)
前述:
第一次發表文章,不過是對數據庫簡單的封裝,主要是闡述下思路。那么在上篇文章,在大家的指導下和提出意見,並自己對代碼進行了思考。在這兩天我重構了新的框架,我覺得我寫的可以稱得上框架,為什么?請大家往下看。不過在項目中沒有很多注釋。筆者除了課余學習時候,大部分時間在完成學校的功課,沒有許多時間,所以也就偷下懶,請大家體諒。
這次框架分為幾個部分:拼接數據庫語句、數據庫執行、數據庫連接控制、異常類、用戶使用的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);
}
}
}
結束:快要熄燈了,沒辦法在寫文章。如果大家對框架有什么不明白,可以在下面評論區問我。這就是更新之后的框架,我覺得還是蠻好用的,雖然還沒經過嚴密的檢測。有什么問題,大家也可以指導下,我也在學習中~

