發布一個自己寫的一個輕量級ORM框架,本框架設計期初基於三層架構.所以從命名上來看,了解三層的朋友會很好理解.
設計該框架的目的:不想重復的寫增刪改查,把精力放到功能實現上.
發布改框架的原因:希望給初學者一個參考,希望能給予好的建議,給自己一個展示機會.
在我開始之前,先說明一下,我對"軟件工程學"概念東西幾乎不通,最高文化程度:初二,所以不喜勿噴.
開始我的orm設計最底層
最底層的是一個DalBase,它是一個抽象的,實現了增刪改查的基本操作.
它既然是一個抽象的,那麼它的內部就不應該有任何具體成員.
它內部核心對象有:訪問數據庫的對象,生成sql文的對象的抽象定義,創建sql參數的抽象方法,where參數化查詢對象的抽象定義.
/// <summary> /// 訪問數據的DBHelper對象 /// </summary> public abstract DbHelperBase DBHelper { get; } //子類實現 /// <summary> /// 獲得生成sql文本的對象 /// </summary> protected internal abstract BuildSQL BuildSQLTextObj { get; } /// <summary> /// 獲得數據參數對象 /// </summary> protected internal abstract DbParameter GetDbParam(string paramName, object paramValue); /// <summary> /// 創建WhereHelper對象 /// </summary> internal abstract WhereHelper CreateWhereHelper();
如需擴展支持的數據庫種類,只需要分別對這幾個抽象對象進行具體代碼的實現.
以下代碼是增刪改(查詢相對來說比較復雜,單獨放出來)
/// <summary> /// 執行sql語句返回所影響行數 /// </summary> public virtual int ExecuteBySQL(string sqlText, Dictionary<string, object> dbParams) { //執行sql語句的操作都由此方法實現 DbParameter[] parameters = GetDbParam(dbParams); int rows = DBHelper.ExecNonQuery(sqlText, parameters); return rows; } /// <summary> /// 新增1條或多條 /// </summary> public virtual int Add<TModel>(params TModel[] models) where TModel : ModelBase, new() { ThrowModelIsNullException(models); string sqlText; Dictionary<string, object> dbParams;
//這句話其實內部實現訪問了 BuildSQLObj 的 InsertSQLTExtAndParam ,它生成sql語句和sql參數對象,把它又寫成方法是為了讓子類還可以對它進行重寫,這個或許之前想多了,直接重寫Add也是可以的. GenerateInsertSQLTextAndParam(out sqlText, out dbParams, models); int rows = ExecuteBySQL(sqlText, dbParams); return rows; } /// <summary> /// 更新一條或多條記錄,根據sql條件,指定更新字段(sqlWhere為空,則按主鍵更新) /// </summary> public virtual int Update<TModel>(string[] fields, string sqlWhere, Dictionary<string, object> dbParams, params TModel[] models) where TModel : ModelBase, new() { ThrowModelIsNullException(models); string sqlText; GenerateUpdateSQLTextAndParam(out sqlText, ref dbParams, sqlWhere, fields, models); int rows = ExecuteBySQL(sqlText, dbParams); return rows; } /// <summary> /// 更新一條或多條記錄,根據sql條件,指定忽略更新的字段 /// </summary> public virtual int UpdateByIgnoreField<TModel>(string[] ignoreFields, string sqlWhere, Dictionary<string, object> dbParams, params TModel[] models) where TModel : ModelBase, new() { string[] allFields = BuildSQLTextObj.GetAllFields<TModel>(); string[] updateFields = BuildSQLTextObj.RemoveFields(allFields, ignoreFields); return Update(updateFields, sqlWhere, dbParams, models); } /// <summary> /// 根據主鍵刪除記錄 /// </summary> public virtual int Delete<TModel>(params object[] pkValues) where TModel : ModelBase, new() { string sqlText; Dictionary<string, object> dbParams; if (pkValues == null || pkValues.Length < 0) { throw new DbDataException("刪除操作時主鍵為空!"); } GenerateDeleteSQLTextAndParam<TModel>(out sqlText, out dbParams, pkValues); int rows = ExecuteBySQL(sqlText, dbParams); return rows; }
查詢提供了,3中方法,返回DataSet,返回List,返回DataReader,以及分頁的方法
public virtual DataTable GetDataTable<TModel>(string sqlWhere, Dictionary<string, object> dbParams, string[] orderFields, bool isDesc, params string[] selectFields) where TModel : ModelBase, new()
{
string sqlText;
GenerateSearchSQLTextAndParam<TModel>(sqlWhere, dbParams, orderFields, isDesc, out sqlText, selectFields);
return GetDataTableBySQL(sqlText, dbParams);
}
public virtual DbDataReader GetDataReader<TModel>(string sqlWhere, Dictionary<string, object> dbParams, string[] orderFields, bool isDesc, params string[] selectFields) where TModel : ModelBase, new()
{
string sqlText;
GenerateSearchSQLTextAndParam<TModel>(sqlWhere, dbParams, orderFields, isDesc, out sqlText, selectFields);
return GetDataReaderBySQL(sqlText, dbParams);
}
public virtual List<TModel> GetList<TModel>(string sqlWhere, Dictionary<string, object> dbParams, string[] orderFields, bool isDesc, params string[] selectFields) where TModel : ModelBase, new()
{
DbDataReader dbReader = GetDataReader<TModel>(sqlWhere, dbParams, orderFields, isDesc, selectFields);
List<TModel> list = GetListByDataReader<TModel>(dbReader);
return list;
}
為什麼有個DataReader方法呢,返回它有兩個用處,1是把它轉換成List,2因為DataSet的獲取內部也是調用了DataReader方法,(通過反編譯可以看到的)
因為DataReader 轉換 List 要比 DataTable to List的效率要快;