大家在用三層架構做開發的時候,是否有使用介面,使用介面的時候是否有類似這樣的代碼: 然後每個每個表都有一個這樣的介面代碼,對比之後發現,這樣的代碼是不是很多重覆呢?那麼有什麼好的辦法可以減少這樣的重覆代碼??? 我想到的是泛型,介面同樣可以泛型,看下麵這張圖,IT_admin,IT_advs,IT_ ...
大家在用三層架構做開發的時候,是否有使用介面,使用介面的時候是否有類似這樣的代碼:
public interface IT_logs { #region 成員方法 /// <summary> /// 得到最大ID /// </summary> int GetMaxId(); /// <summary> /// 是否存在該記錄 /// </summary> bool Exists(int Id); /// <summary> /// 增加一條數據 /// </summary> int Add(Maticsoft.Model.T_logs model); /// <summary> /// 更新一條數據 /// </summary> bool Update(Maticsoft.Model.T_logs model); /// <summary> /// 刪除一條數據 /// </summary> bool Delete(int Id); bool DeleteList(string Idlist ); /// <summary> /// 得到一個對象實體 /// </summary> Maticsoft.Model.T_logs GetModel(int Id); Maticsoft.Model.T_logs DataRowToModel(DataRow row); /// <summary> /// 獲得數據列表 /// </summary> DataSet GetList(string strWhere); /// <summary> /// 獲得前幾行數據 /// </summary> DataSet GetList(int Top,string strWhere,string filedOrder); int GetRecordCount(string strWhere); DataSet GetListByPage(string strWhere, string orderby, int startIndex, int endIndex); /// <summary> /// 根據分頁獲得數據列表 /// </summary> //DataSet GetList(int PageSize,int PageIndex,string strWhere); #endregion 成員方法 #region MethodEx #endregion MethodEx }
然後每個每個表都有一個這樣的介面代碼,對比之後發現,這樣的代碼是不是很多重覆呢?
那麼有什麼好的辦法可以減少這樣的重覆代碼???
我想到的是泛型,介面同樣可以泛型,看下麵這張圖,IT_admin,IT_advs,IT_artClass......,它們內部代碼幾乎一模一樣
如果我們寫這樣的一個泛型介面,那麼這一個介面就代替了上面所有的Idal介面,並且你再增加表,也不需要添加Idal的介面文件了,是不是很爽?
public interface IOperate<T> { bool UpdateData(T entityData);//添加、編輯 bool Delete(int Id);//根據ID號刪除數據 DataTable GetTable(string where, string orderBy, int pageIndex, int pageSize, out int recordCount);//返回數據表 List<T> GetList(string sqlsStr);//返回LIST T GetDataById(int Id);//返回實體對象 }
代碼很簡單,我就不多做解釋了,然後我們用每個DAL去實現這個介面,就可以,這樣就不需要去為每個DAL單寫一個介面了,要知道,每個DAL里的操作90%都是相同的,當然,我們也可以擴展一些其它方法出來。
其實為每個表寫DAL中,也是有功能可以抽象出來的,比如:刪除,判斷ID號是否存在,每個DAL所操作的表名,和表的主鍵,還有資料庫操作對象,這些內容其實也可以抽象出來,所以我想到建立一個DALBASE的抽象類,提供一些虛方法,如果哪個DAL不一樣,那就重寫虛方法就可以了。所以有了下麵這個類
public abstract class DalBase { protected string TableName { set; get; } protected string PkField { set; get; } protected Database da = DatabaseFactory.CreateDatabase(); /// <summary> /// 刪除 /// </summary> /// <param name="Id"></param> /// <returns></returns> public virtual bool Delete(int Id) { var sqlStr = "delete from {0} where {1}=@Id"; sqlStr = string.Format(sqlStr, this.TableName, this.PkField); var command = da.GetSqlStringCommand(sqlStr); da.AddInParameter(command, "@Id", DbType.Int32, Id); return da.ExecuteNonQuery(command) > 0; } /// <summary> /// 判斷是否存在 /// </summary> /// <param name="Id"></param> /// <returns></returns> public virtual bool IsExists(int Id) { var sqlStr = "select count(*) from @TableName where @PkField=@Id"; var command = da.GetSqlStringCommand(sqlStr); da.AddInParameter(command, "@TableName", DbType.String, this.TableName); da.AddInParameter(command, "@PkField", DbType.String, this.PkField); da.AddInParameter(command, "@Id", DbType.Int32, Id); var obj = da.ExecuteScalar(command); if (obj != null && !Convert.IsDBNull(obj)) { return int.Parse(obj.ToString()) > 0; } return false; } }
那麼DAL類的代碼應該是怎麼樣?
public class AdminDal : DalBase, IOperate<AdminEntity> { public AdminDal() { this.TableName = "T_Admin"; this.PkField = "Id"; } /// <summary> /// 添加,編輯 /// </summary> /// <param name="entityData"></param> /// <returns></returns> public bool UpdateData(AdminEntity entityData) { var sqlStr = string.Empty; DbCommand command; if (entityData.Id == 0)//添加 { sqlStr = @"insert into {0}(UserName,UserPwd,Flag,PostTime) values(@UserName,@UserPwd,@Flag,@PostTime)"; sqlStr = string.Format(sqlStr, this.TableName); command = da.GetSqlStringCommand(sqlStr); } else//編輯 { sqlStr = @"update {0} set UserPwd=@UserPwd,Flag=@Flag,PostTime=@PostTime where {1}=@Id"; sqlStr = string.Format(sqlStr, this.TableName, this.PkField); command = da.GetSqlStringCommand(sqlStr); da.AddInParameter(command, "@Id", DbType.Int32, entityData.Id); } da.AddInParameter(command, "@UserName", DbType.String, entityData.UserName); da.AddInParameter(command, "@UserPwd", DbType.String, entityData.UserPwd); da.AddInParameter(command, "@Flag", DbType.String, entityData.Flag); da.AddInParameter(command, "@PostTime", DbType.DateTime, entityData.PostTime); return da.ExecuteNonQuery(command) > 0; } public List<AdminEntity> GetList(string sqlStr) { var list = new List<AdminEntity>(); var command = da.GetSqlStringCommand(sqlStr); var dt = da.ExecuteDataSet(command).Tables[0]; if (dt != null && dt.Rows.Count > 0) { foreach (DataRow dr in dt.Rows) { var entity = new AdminEntity() { Id = int.Parse(dr["Id"].ToString()), UserName = dr["UserName"].ToString(), UserPwd = dr["UserPwd"].ToString(), Flag = dr["Flag"].ToString(), PostTime = DateTime.Parse(dr["PostTime"].ToString()) }; list.Add(entity); } } return list; } //分頁查詢,需要SQL2005 以上的版本支持 /*private const string DefaultSqlStr = @" SELECT * FROM ( SELECT row_number() OVER({0}) as ROW_NUMBER,* FROM ( SELECT * FROM T_admin {1} ) as a ) as b WHERE ROW_NUMBER > {2} AND ROW_NUMBER <= {3}"; */ //分頁查詢 private const string DefaultSqlStr = @"select top {0} * from {1} where {2} not in (select top {3} {4} from {5} where 1=1 {6} {7}) {8} {9} "; private const string DefaultSqlCount = @"select count(*) FROM {0} where 1=1 {1}"; public DataTable GetTable(string where, string orderBy, int pageIndex, int pageSize, out int recordCount) { var sql = String.Format(DefaultSqlCount, this.TableName, where); var obj = da.ExecuteScalar(CommandType.Text, sql); recordCount = 0; if (obj != null && !Convert.IsDBNull(obj)) { recordCount = int.Parse(obj.ToString());//記錄條數 } pageIndex = pageIndex > 0 ? pageIndex : 1;//最小為1 if (string.IsNullOrEmpty(orderBy)) { orderBy = " order by " + this.PkField + " Desc"; } sql = String.Format(DefaultSqlStr, pageSize, this.TableName, this.PkField, (pageIndex - 1) * pageSize, this.PkField, this.TableName, where, orderBy, where, orderBy); return da.ExecuteDataSet(CommandType.Text, sql).Tables[0]; } public AdminEntity GetDataById(int Id) { var sqlStr = "select * from {0} where {1}=@Id"; sqlStr = string.Format(sqlStr, this.TableName, this.PkField); var command = da.GetSqlStringCommand(sqlStr); da.AddInParameter(command, "@Id", DbType.Int32, Id); var dt = da.ExecuteDataSet(command).Tables[0]; if (dt != null && dt.Rows.Count > 0) { var dr = dt.Rows[0]; var entity = new AdminEntity() { Id = int.Parse(dr["Id"].ToString()), UserName = dr["UserName"].ToString(), UserPwd = dr["UserPwd"].ToString(), Flag = dr["Flag"].ToString(), PostTime = DateTime.Parse(dr["PostTime"].ToString()) }; return entity; } return null; } }
DAL類繼承了DalBase,並實現了泛型介面。。
最後我們要完成Bll類:
public class AdminBll { private static readonly IOperate<AdminEntity> iDal = new AdminDal(); public static bool UpdateData(AdminEntity entity) { return iDal.UpdateData(entity); } public static bool Delete(int Id) { return iDal.Delete(Id); } public static List<AdminEntity> GetList(string sqlStr) { return iDal.GetList(sqlStr); } public static DataTable GetTable(string where, string orderBy, int pageIndex, int pageSize, out int recordCount) { return iDal.GetTable(where, orderBy, pageIndex, pageSize, out recordCount); } public static AdminEntity GetDataById(int id) { return iDal.GetDataById(id); } }
那麼,當我們需要調用方法的時候,代碼是怎麼樣的?
var adminEntity = new AdminEntity() { UserName = "admin888", UserPwd = "admin888", Flag = "0", PostTime = DateTime.Now }; AdminBll.UpdateData(adminEntity);
這樣就實現了一個添加的操作。。。
其實我自己並不確定這樣去使用泛型介面是否合理,歡迎大家噴,但請告訴我原因,因為我自認自己是菜鳥,需要學習。。。