When you are developing with a three-tier architecture, do you have a code that uses interfaces when you use interfaces like this:
Public interface It_logs {#region member method///<summary>//Get maximum ID//</SUMMARY> ; int GetMaxID (); <summary>///Whether the record exists///</summary> bool Exists (int Id); <summary>////Add a data////</summary> int Add (Maticsoft.Model.T_logs Model); <summary>///update a data///</summary> bool Update (Maticsoft.Model.T_logs Model); <summary>///delete a data///</summary> bool Delete (int Id); BOOL DeleteList (string idlist); <summary>///Get an Object entity///</summary> Maticsoft.Model.T_logs getmodel (int Id); Maticsoft.Model.T_logs Datarowtomodel (DataRow row); <summary>///Get Data List///</summary> DataSet GetList (String strwhere); <summary>///Get previous lines of data///</SUMMARY> DataSet GetList (int top,string strwhere,string filedorder); int GetRecordCount (string strwhere); DataSet getlistbypage (String strwhere, string by, int startIndex, int endIndex); <summary>//////</summary>//dataset GetList (int pagesize,int PageIndex)///per page// String strwhere); #endregion member Method #region Methodex #endregion Methodex}
Then each table has one such interface code, compared to find out, such code is not a lot of repetition?
So what is the best way to reduce this duplication of code???
I think of generics, the interface can also be generic, see the following picture, It_admin,it_advs,it_artclass ..., their internal code is almost identical
If we write such a generic interface, then this one interface instead of all of the above Idal interface, and you add the table, and do not need to add Idal interface files, is not very cool?
Public interface ioperate<t> { bool UpdateData (T entitydata);//Add, edit bool Delete (int Id);// Delete data based on ID number DataTable GetTable (string where, string by, int pageIndex, int pageSize, out int recordCount);//Return data table C6/>list<t> GetList (string sqlsstr);//return List T getdatabyid (int Id);//Return entity object }
The code is very simple, I do not explain more, and then we use each DAL to implement this interface, so we do not need to write a single interface for each DAL, you know, each DAL operation 90% is the same, of course, we can also extend some other methods out.
In fact, for each table to write the DAL, there are functions can be abstracted out, such as: Delete, determine whether the ID number exists, the table name of each DAL operation, and the table's primary key, as well as database operations objects, which can actually be abstracted out, so I think to build a dalbase abstract class, Provide some virtual methods, if the DAL is different, then rewrite the virtual method is okay. So with the following class
Public abstract class Dalbase {protected string TableName {set; get;} Protected string Pkfield {set; get;} protected Database da = Databasefactory.createdatabase (); <summary>//delete///</summary>//<param name= "Id" ></param>// <returns></returns> Public virtual BOOL Delete (int Id) {var sqlstr = ' Delete from {0 } where {1}[email protected] "; 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>//To determine if there is a///</summary>//<param name= "Id" ></param> <returns></returns> Public virtual bool Isexists (int Id) {var sqlstr = "Sele CT Count (*) from @TaBlename where @[email protected] "; 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; } }
So what should the Dal class code be like?
public class Admindal:dalbase, ioperate<adminentity> {public admindal () {this. TableName = "T_admin"; This. Pkfield = "Id"; }///<summary>//Add, edit///</summary>//<param name= "Entitydata" ></p aram>//<returns></returns> public bool UpdateData (adminentity entitydata) { var sqlstr = string. Empty; DbCommand command; if (entitydata.id = = 0)//Add {sqlstr = @ "insert into {0} (Username,userpwd,flag,posttime) VALUES ( @UserName, @UserPwd, @Flag, @PostTime) "; Sqlstr = string. Format (Sqlstr, this. TableName); Command = da. Getsqlstringcommand (SQLSTR); } else//Edit {sqlstr = @ "Update {0} set [email protected],[email protected], [email protected] where {1}[email protected] "; 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; }//Paging query, need SQL2005 above version support/*private const string DEFAULTSQLSTR = @ "SELECT * FROM (Selec T 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} "; *////Paging Query 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 by, 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 ());//Record Bar} PageIndex = pageIndex > 0? pageindex:1;//Minimum is 1 if (string. IsNullOrEmpty) {ORDER by +-this. Pkfield + "Desc"; sql = String.Format (defaultsqlstr, PageSize, this. TableName, this. Pkfield, (pageIndex-1) * pageSize, this. Pkfield, this. TableName, where, by-and-by, where, as-is); Return DA. ExecuteDataset (CommandType.Text, SQL). Tables[0]; } public adminentity Getdatabyid (int Id) {var sqlstr = "Select * FROM {0} where {1}[email protected]"; 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; } }
The Dal class inherits the Dalbase and implements the generic interface.
Finally we are going to complete the BLL class:
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 by, int pageIndex, int pageSize, out int recordCount) {
return idal.gettable (where, by, PageIndex, PageSize, out recordCount); } public static adminentity Getdatabyid (int id) { return Idal.getdatabyid (ID); } }
So, what is the code like when we need to invoke the method?
var adminentity = new Adminentity () { UserName = "admin888", userpwd = "admin888", Flag = "0", Posttime = DateTime.Now }; Adminbll.updatedata (adminentity);
This enables an added operation ...
In fact, I am not sure to use the generic interface is reasonable, welcome everyone to spray, but please tell me the reason, because I think I am a rookie, need to learn ...
Discussion on the generic interface