通过反射泛型实体类的另类的DAL层
2013-02-22 12:52 CodeCy 阅读(816) 评论(0) 编辑 收藏 举报先上DbHelper
View Code
DalBase源码如下:有详细注释
/************************************************* 功能:DAL层, 增,删,改,查通用方法 说明:增,删,改 通过反射实体类,自动生成sql语句 查询方法使用反射填充对象实体 编码:liguozhong 修改时间:2012-8-25 ************************************************/ using System; using System.Collections; using System.Data; using System.Data.SqlClient; using System.Reflection; using System.Collections.Generic; using System.Linq; using System.Text; namespace Dal { public class DalBase<T> { //获取表标识列 //TableName 数据表名称 private List<string> TableIdentity(string TableName) { //建立字符串列表 List<string> List<string> myList = new List<string>(); //数据库数据库SQL语名 强记系统自带SQL语句 string strSql = "select name from syscolumns " + " where COLUMNPROPERTY( id,name,'IsIdentity')=1 " + " and id=object_id('" + TableName + "')"; //Using自动释放对象 //新建 sqldatareader对象,用来存放查询出来的数据 using (SqlDataReader myReder = DbHelper.SelectReader(strSql)) { //myReader.Read() 循环所有查询的出来的数据 Read() 表示读取下一条 while (myReder.Read()) { //把第一列,添加到List列表 myList.Add(myReder[0].ToString()); } //返回所有表识列列表 return myList; } } /// <summary> /// 返回表主键列表 /// </summary> /// <param name="tableName">表名</param> /// <returns>List</returns> private List<string> PrimaryNameList(string tableName) { //主键名称列表 List<string> myList = new List<string>(); //新建用来保存 表名的sql参数 @table_name tableName 表示:表名 SqlParameter par = new SqlParameter("@table_name", tableName); //新建用来保存 //建参数列表,保存sql参数 List<SqlParameter> myParList = new List<SqlParameter>(); //把sql参数,添加参数列表中 myParList.Add(par); //uinsg 自动释放对象 //sqlDataReader保存查询出来的数据 //sp_pkeys 表示:用来查询表主键的存储过程, 是系统自定义的 //myParList 表示:存储过程用到的 sql参数列表, //true 表示: SelectReader方法,调用的是存储过程 using (SqlDataReader myRead = Dal.DbHelper.SelectReader("sp_pkeys", myParList, true)) { //循环读取下一条记录 while (myRead.Read()) { //把记录添加到主键集合 myList.Add(myRead["column_name"].ToString()); } } //返回主键列表 return myList; } /// <summary> /// 插入 /// </summary> /// <param name="obj">实体对象</param> /// <returns>受影响数据</returns> /// T 表示:实例类传进来的类型 如:new DalBase<Model.meun> 那 T就=meun public string Insert(T obj) { //获取类型 Type T = obj.GetType(); //获取标识列列表 List<string> primList = TableIdentity(T.Name); //获取主键 List<string> PkList = PrimaryNameList(T.Name); //获取类型属性 PropertyInfo[] pArr = T.GetProperties(); //新建SQL参数列表,用来保存插入SQL语句用的SQL参数 List<SqlParameter> myParList = new List<SqlParameter>(); //用来保存SQl语句 列名的字符串 如:id,name,sex,age string strK = ""; //用来保存sql语句 列名值的字符串 如:@id,@name,@sex,@age string strV = ""; //循环遍历类中每个属性 pArr 表示:类所有属性 p 表示:单个属性 如:id,name foreach (PropertyInfo p in pArr) { //判断属性不是标识列 !primList.Contains(p.Name) //再次判断属性不为空 p.GetValue(obj, null)!=null //如果属性不为标识列且不为空,就组装 把:列名,SQL参数,SQl参数值 添加到SQL语句当中 if (!primList.Contains(p.Name)&&p.GetValue(obj, null)!=null) { //组装列名 如strk+strK+p.Name+"," //P.Name 表示:单个属性的名称 与数据库列名一致 最后结果如:id,name,sex,age, strK += p.Name + ","; //@+P.Name 表示:单个属性在Sql语句用到的SQL变量 如:@id 最后结果如:@id,@name,@sex,@age, strV += "@" + p.Name + " ,"; //新建SQL变量对象保存 属性在SQL语句中用到Sql参数 如:@id //"@"+p.Name 表示:@加上p的属性名称 //p.GetValue 表示:获取对象ojb的属性内容值 null 表示:此属性不为集合是单个变量 SqlParameter par = new SqlParameter("@" + p.Name, p.GetValue(obj, null)); //把Sql变量添加到SQL变量列表当中 myParList.Add(par); } } //由于组装strK值的时间后面多一个"," 所有要去掉最后一个字符 //strK!="" 判断字符是否为空 if (strK != "") { //subtring获取字串 0:表示 从0下标开始 strk.Length-1 表示:要获取的总字符数 strK = strK.Substring(0, strK.Length - 1); } //由于组装strK值的时间后面多一个"," 所有要去掉最后一个字符 if (strV != "") { //subtring获取字串 0:表示 从0下标开始 strk.Length-1 表示:要获取的总字符数 strV = strV.Substring(0, strV.Length - 1); } //StringBuilder 字串符对象,比Stirng 相加 的效率高很多 StringBuilder SB = new StringBuilder(); //Append 相当于string 的相加 //obj.GetType().Name 表示:获取表的名称 由于类的名称与数据库表一致 SB.Append("insert into " + obj.GetType().Name + " ("); //strK 表示:列名 如:id,name SB.Append(strK + ")"); //output inserted:表示返回表中的某列; SB.Append(" output inserted." + PkList[0] + " values ("); //strV 表示:列名SQl变量 如:@id,@name SB.Append(strV + ")"); //List列表,转成数组 //由于CUD的方法,只接收SqlParameter数组,下面把List<SqlParameter> 转换SQL数组; SqlParameter[] myArrPar = myParList.ToArray(); //调用CUD增,删,改通用方法 返回受影响的总数 //SB.ToString 表示:SQl语句 myArrPar 表示:SQL参数数组 return DbHelper.Insert(SB.ToString(), myArrPar).ToString(); } /******************************************************** 目的:组装修改SQL语名 update 表名 Set 列名=@列名 where 主列名=@主键列名 ************************************************************/ //修改 T 表示:传进来的类型 如:new DalBase<Model.Memu> T就代表Meum类型 public int Update(T obj) { //获取类型 Type T = obj.GetType(); //获取主键列表 由于修改时不能修改主键,要把主键做为修改条件 所以要把主键列查出来 List<string> primList = PrimaryNameList(T.Name); //获取标识列表 由于修改时不能修改标识列,所以要把标识查出来,不参与修改语句组装 List<string> identityList = TableIdentity(T.Name); //获取类型的所有属性,以便遍历 PropertyInfo[] pArr = T.GetProperties(); //新建SQl参数列表,用保存Sql语句调用的SQL参数 List<SqlParameter> myParList = new List<SqlParameter>(); //用来保存组装SQL语句列名 如:id=@id,name=@name,sex=@sex string strK = ""; //用来保存SQL语句组装时的条件 如:id=@id and name=@name string strWhere=""; //遍历类所有属性,来组装 列名(strK),条件(strWhere),SQl参数 //pArr表示:所有属性, P 表示:单个属性 foreach (PropertyInfo p in pArr) { //由于主键不能修改,要用来做修改语句的条件所以要判断属性是否存在主键中 //判断属性是否存在主键中 !primList.Contains(p.Name) //p.Name 表示:p的属性名 if (!primList.Contains(p.Name)) { //判断属性是否存在标识中 原因:数据库标识列不能修改 //!identityList.Contains(p.Name) 判断p的属性值是否存在标识列表中 //判断属性内容是否为空,原因:属性值为空的话,就没有必要修改 // p.GetValue(obj, null) != null if (!identityList.Contains(p.Name)&& p.GetValue(obj, null) != null) { //组装SQl修改部分 最后结果如:name=@name,sex=@sex strK += p.Name + "=@" + p.Name + ","; //把SQL修改部分用到的SQ变量,添加到SQL变量列表中 //p.GetValue(obj, null) 表示:获取对象ojb的属性内容值 null:表示些属性不是集合 SqlParameter par = new SqlParameter("@" + p.Name, p.GetValue(obj, null)); myParList.Add(par); } } else { //如果属性值不存在主键中,则会成为条件一部分 如:where //组装条件 p.Name 表示:属性名称 strWhere += " and " +p.Name + "=@" +p.Name; //把条件语句Where 用到的SQL参数变量添加到SQl变量集中 SqlParameter par = new SqlParameter("@" + p.Name, p.GetValue(obj, null)); myParList.Add(par); } } //判断是SQl修改语句是否为空 if (strK != "") { //由于SQl修改语名后面带,所以要去掉 strK = strK.Substring(0, strK.Length - 1); } //StringBuilder 表示:字符串对象,比string 的效率高的多 StringBuilder SB = new StringBuilder(); //Append 追加字符串,相当中string 的加号(+) //obj.GetType().Name 表示:获取类型名,由于类型名与表名一致,相当于获取表名 SB.Append("update " + obj.GetType().Name + " set "); SB.Append(strK); SB.Append(" where 1=1 "); SB.Append(strWhere); //由于CUD方法只接收SqlParameter[]数组,所以要转换 SqlParameter[] myArrPar = myParList.ToArray(); //调用CUD方法,返回受影响总数 return DbHelper.CUD(SB.ToString(), myArrPar); } /****************************************************** * 目的:组装SQl删除语句 * delete 表名 where 主键列=@主键列名 * ******************************************************/ //T 表示:实例化 DalBase<T> 对象传入的类型 如:new DalBase<Model.Menu> T就代表Menu public int Delete(T obj) { //获取类型 Type T = obj.GetType(); //获取主键列表 List<string> primList = PrimaryNameList(T.Name); //获取类型所有属性 T.GetProperties() PropertyInfo[] pArr = T.GetProperties(); //创建SQL变是列表,用来保存SQL语句用到的SQL变量 List<SqlParameter> myParList = new List<SqlParameter>(); //用来保存SQL条件的字符串 如: id=@id and name=@name string strWhere = ""; //循环遍历属性集合 pArr 表示:所有属性 p 表示:单个属性值 foreach (PropertyInfo p in pArr) { //判断属性是否存在主键列表中,如果存在则,组装条件语句 //原因:删除语句只需要条件语句 如:where id=@id if (primList.Contains(p.Name)) { //判断是主键内容值是否为空,空不则不组装 if (p.GetValue(obj, null) != null) { //组装Sql条件语名,最后结果如:and id=@id and name=@name, strWhere +=" and "+ p.Name + "=@" + p.Name + ","; //把SQl条件语句用到SQL参数,添加到SQL参数列表中 //p.GetValue(obj, null) 表示:获取obj对象的属性内容值 null:此属性不为集合 SqlParameter par = new SqlParameter("@" + p.Name, p.GetValue(obj, null)); myParList.Add(par); } } } //判断是条件语句是否为空 if (strWhere != "") { //去掉条件语句后面的","号 strWhere = strWhere.Substring(0,strWhere.Length-1); } //创建StringBuilder对象,来组装SQL语名 原因:比string效率高很多 StringBuilder SB = new StringBuilder(); // obj.GetType().Name 获取类型名称,由于类型名与数据库表名一致,就相当于获取表名 SB.Append("delete " + obj.GetType().Name); SB.Append(" where 1=1 "); SB.Append(strWhere); //把SQL参数列表,转成SQL参数数组 SqlParameter[] myArrPar = myParList.ToArray(); //调用CUD,增,删 ,改通用方法,返回受影响的数量 return DbHelper.CUD(SB.ToString(), myArrPar); } //批量删除 public int Delete(List<T> obj) { int j = 0; for (int i = 0; i <obj.Count; i++) { j+= Delete(obj[i]); } return j; } //批量删除 public int Delete(string strSql) { return DbHelper.CUD(strSql); } /// <summary> /// 返回单个对象 /// </summary> /// <param name="strWhere">查询条件 如: and id=10 and name='中国'</param> /// <returns>单个对象</returns> public T SelectSingle(string strWhere ) { List<T> myList= Select(strWhere, null); if (myList.Count > 0) { return myList[0]; } else { //返回初始值,什么都没有; return default(T); } } /// <summary> /// 单表查询 自动生成返回列 /// </summary> /// <param name="strWhere">查询条件 如:and id>@id and name=@name 没有则为:Null</param> /// <param name="WhereSqlParameter">Sql参数变量 没有则为:Null</param> /// <returns></returns> public List<T> Select(string strWhere,List<SqlParameter> WhereSqlParameter) { List<T> myList = new List<T>(); try { //获取类型 Type U=typeof(T); //获取类型属性 PropertyInfo[] pArr = U.GetProperties(); //获取Sql参数 List<SqlParameter> myParList = new List<SqlParameter>(); string strK = ""; foreach (PropertyInfo p in pArr) { strK += p.Name + ","; } if (strK != "") { strK = strK.Substring(0, strK.Length - 1); } StringBuilder SB = new StringBuilder(); SB.Append("select "); SB.Append(strK); SB.Append(" from "+U.Name); if (strWhere != null && strWhere != "") { SB.Append(" where 1=1 " + strWhere); } using (SqlDataReader myReader = Dal.DbHelper.SelectReader(SB.ToString(), WhereSqlParameter)) { while (myReader.Read()) { //实例化一个类型对象 Type myType = typeof(T); //跟据类型创建对象 object obj = Activator.CreateInstance(myType); //循环列所有例 for (int i = 0; i < myReader.FieldCount; i++) { //得到对映的属性 //myReader.GetName(i) 获取列名 PropertyInfo pro = myType.GetProperty(myReader.GetName(i)); object val = myReader[i]; //判断对象是否为空,属性是否为空,属性是否可写! if (val != DBNull.Value && pro != null && pro.CanWrite) { //给属性赋值 //obj 指对象 //myReader[i]对象的值 //null 不是为索引 pro.SetValue(obj, myReader[i], null); } } myList.Add((T)obj); } } return myList; } catch (Exception ex) { return null; } } ///<summary> ///单表查询 ///</summary> ///<param name="strSql">sql语句 如:selec * from aa where id=1</param> ///<returns>list</returns> public List<T> Select(string strSql) { List<T> myList = new List<T>(); try { List<SqlParameter> myParList = new List<SqlParameter>(); using (SqlDataReader myReader = Dal.DbHelper.SelectReader(strSql, null)) { while (myReader.Read()) { //实例化一个类型对象 Type myType = typeof(T); //跟据类型创建对象 object obj = Activator.CreateInstance(myType); //循环列所有例 for (int i = 0; i < myReader.FieldCount; i++) { //得到对映的属性 //myReader.GetName(i) 获取列名 PropertyInfo pro = myType.GetProperty(myReader.GetName(i)); object val = myReader[i]; //判断对象是否为空,属性是否为空,属性是否可写! if (val != DBNull.Value && pro != null && pro.CanWrite) { //给属性赋值 //obj 指对象 //myReader[i]对象的值 //null 不是为索引 pro.SetValue(obj, myReader[i], null); } } myList.Add((T)obj); } } return myList; } catch (Exception ex) { return null; } } /// <summary> /// 多表查询 注意:列结果要与对象属性名一致 /// </summary> /// <param name="strSql">Sql语名 如:select id,name from tableName 注意id,name要与属性名一致</param> /// <param name="strWhere">Where条件 如:id=@id and name=@name</param> /// <param name="WhereSqlParameter">SqlParameterList列表 说明:没有参数则为 null</param> /// <returns>List对象集合</returns> public List<T> Select(string strSql,string strWhere, List<SqlParameter> WhereSqlParameter) { List<T> myList = new List<T>(); try { //获取类型 Type U = typeof(T); //获取类型属性 PropertyInfo[] pArr = U.GetProperties(); //获取Sql参数 List<SqlParameter> myParList = new List<SqlParameter>(); string strK = ""; foreach (PropertyInfo p in pArr) { strK += p.Name + ","; } if (strK != "") { strK = strK.Substring(0, strK.Length - 1); } StringBuilder SB = new StringBuilder(); SB.Append(strSql); if (strWhere != null && strWhere != "") { SB.Append(" where 1=1 " + strWhere); } using (SqlDataReader myReader = Dal.DbHelper.SelectReader(SB.ToString(), WhereSqlParameter)) { while (myReader.Read()) { //实例化一个类型对象 Type myType = typeof(T); //跟据类型创建对象 object obj = Activator.CreateInstance(myType); //循环列所有例 for (int i = 0; i < myReader.FieldCount; i++) { //得到对映的属性 //myReader.GetName(i) 获取列名 PropertyInfo pro = myType.GetProperty(myReader.GetName(i)); object val = myReader[i]; //判断对象是否为空,属性是否为空,属性是否可写! if (val != DBNull.Value && pro != null && pro.CanWrite) { //给属性赋值 //obj 指对象 //myReader[i]对象的值 //null 不是为索引 pro.SetValue(obj, myReader[i], null); } } myList.Add((T)obj); } } return myList; } catch (Exception ex) { return null; } } // 分页公式 //select top {0} * from TeacherInfo where UserID not in(select top {1} UserID from TeacherInfo )",pageSize,(index-1)*pageSize /// <summary> /// 分页查询 /// </summary> /// <param name="strWhere">条件 </param> /// <param name="WhereSqlParameter">sql参数</param> /// <param name="pageSize">页面大小</param> /// <param name="Page">当前页</param> /// <param name="count">返回总页数</param> /// <returns></returns> // public List<T> Select(string strWhere, List<SqlParameter> WhereSqlParameter,int pageSize,int Page,ref int count) //{ // List<T> myList = new List<T>(); // try // { // //获取类型 // Type U = typeof(T); // //获取类型属性 // PropertyInfo[] pArr = U.GetProperties(); // //获取Sql参数 // List<SqlParameter> myParList = new List<SqlParameter>(); // string strK = ""; // foreach (PropertyInfo p in pArr) // { // strK += p.Name + ","; // } // if (strK != "") // { // strK = strK.Substring(0, strK.Length - 1); // } // //获取主键 // List<string> primList = PrimaryNameList(U.Name); // StringBuilder countSB = new StringBuilder(); // countSB.Append("select count(*) from "+U.Name); // if (strWhere != null && strWhere != "") // { // countSB.Append(" where 1=1 " + strWhere); // } // //查出总记录数 // using (SqlDataReader countReader = Dal.DbHelper.SelectReader(countSB.ToString(), WhereSqlParameter)) // { // while (countReader.Read()) // { // //总记录数 // count =countReader[0]!=null? Convert.ToInt32(countReader[0]):0; // break; // } // } // StringBuilder SB = new StringBuilder(); // SB.Append("select top "+pageSize+" "); // SB.Append(strK); // SB.Append(" from " + U.Name); // if (strWhere != null && strWhere != "") // { // SB.Append(" where " + primList[0] + " not in(select top " + (Page - 1) * pageSize + " " + primList[0] + " from " + U.Name + " ) and " + strWhere); // } // else // { // SB.Append(" where " + primList[0] + " not in(select top " + (Page - 1) * pageSize + " " + primList[0] + " from " + U.Name + ")"); // } // using (SqlDataReader myReader = Dal.DbHelper.SelectReader(SB.ToString(), WhereSqlParameter)) // { // while (myReader.Read()) // { // //实例化一个类型对象 // Type myType = typeof(T); // //跟据类型创建对象 // object obj = Activator.CreateInstance(myType); // //循环列所有例 // for (int i = 0; i < myReader.FieldCount; i++) // { // //得到对映的属性 // //myReader.GetName(i) 获取列名 // PropertyInfo pro = myType.GetProperty(myReader.GetName(i)); // object val = myReader[i]; // //判断对象是否为空,属性是否为空,属性是否可写! // if (val != DBNull.Value && pro != null && pro.CanWrite) // { // //给属性赋值 // //obj 指对象 // //myReader[i]对象的值 // //null 不是为索引 // pro.SetValue(obj, myReader[i], null); // } // } // myList.Add((T)obj); // } // } // return myList; // } // catch (Exception ex) // { // return null; // } //} /// <summary> /// 分页通用方法 /// </summary> /// <param name="strWhere">查询条件</param> /// <param name="WhereSqlParameter">查询条件SQl参数</param> /// <param name="pageSize">页面大小</param> /// <param name="page">当前页</param> /// <param name="count">总数行</param> /// <returns></returns> public List<T> Select(string strWhere, List<SqlParameter> WhereSqlParameter,int pageSize,int page,ref int count) { List<T> myList = new List<T>(); try { //获取类型 Type U = typeof(T); //获取类型属性 PropertyInfo[] pArr = U.GetProperties(); //获取Sql参数 List<SqlParameter> myParList = new List<SqlParameter>(); string strK = ""; foreach (PropertyInfo p in pArr) { strK += p.Name + ","; } if (strK != "") { strK = strK.Substring(0, strK.Length - 1); } StringBuilder countSb =new StringBuilder(); countSb.Append("select count(*) from " + U.Name); if (strWhere != null && strWhere != "") { countSb.Append(" where 1=1 " + strWhere); } using (SqlDataReader countReader = Dal.DbHelper.SelectReader(countSb.ToString())) { //向下读一条记录 countReader.Read(); //获取总行数 count = countReader[0] == null ? 0 : Convert.ToInt32(countReader[0]); } //获取表主键 List<string> myPrim = PrimaryNameList(U.Name); StringBuilder SB = new StringBuilder(); SB.Append("select top "+pageSize+" "); SB.Append(strK); SB.Append(" from " + U.Name); //主键总数是否>0用来 判断是:单表还是多表查询 if (myPrim.Count > 0) { if (strWhere != null && strWhere != "") { SB.Append(" where 1=1 and " + myPrim[0] + " not in (select top " + pageSize * (page - 1) + " " + myPrim[0] + " from " + U.Name + " order by " + myPrim[0]+" ) " + strWhere + " order by " + myPrim[0]); } else { SB.Append(" where 1=1 and " + myPrim[0] + " not in (select top " + pageSize * (page - 1) + " " + myPrim[0] + " from " + U.Name +" order by " + myPrim[0]+ ") order by " + myPrim[0]); } } else { //视图查询 if (strWhere != null && strWhere != "") { SB.Append(" where 1=1 and " + pArr[0].Name + " not in (select top " + pageSize * (page - 1) + " " + pArr[0].Name + " from " + U.Name + " order by " + pArr[0].Name + " ) " + strWhere +" order by "+ pArr[0].Name); } else { SB.Append(" where 1=1 and " + pArr[0].Name + " not in (select top " + pageSize * (page - 1) + " " + pArr[0].Name + " from " + U.Name + " order by " + pArr[0].Name +") order by " + pArr[0].Name ); } } using (SqlDataReader myReader = Dal.DbHelper.SelectReader(SB.ToString(), WhereSqlParameter)) { while (myReader.Read()) { //实例化一个类型对象 Type myType = typeof(T); //跟据类型创建对象 object obj = Activator.CreateInstance(myType); //循环列所有例 for (int i = 0; i < myReader.FieldCount; i++) { //得到对映的属性 //myReader.GetName(i) 获取列名 PropertyInfo pro = myType.GetProperty(myReader.GetName(i)); object val = myReader[i]; //判断对象是否为空,属性是否为空,属性是否可写! if (val != DBNull.Value && pro != null && pro.CanWrite) { //给属性赋值 //obj 指对象 //myReader[i]对象的值 //null 不是为索引 pro.SetValue(obj, myReader[i], null); } } myList.Add((T)obj); } } return myList; } catch (Exception ex) { return null; } } } }