反射入門-淺談反射用途_根據Ado遊標對象創建list集合
阿新 • • 發佈:2017-05-18
cep exists _id tostring ogr param char typeof scala
本人大二菜鳥一只,今天在上課期間有個同學看著C#反射的內容說反射沒什麽用,一時之間也想不到什麽更好的例子,就寫了個根據泛型類型和遊標反射創建List集合的Demo.
首先創建一個用於封裝對應數據的entity,代碼如下.
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Test { public class EUserInfo { public int UserId { get; set; } public string UserCode { get; set; } public string UserName { get; set; } public string UserPwd { get; set; } public string Gender { get; set; } public override string ToString() { return "UserId:"+UserId+"|UserCode:"+UserCode+"|UserName:"+UserName+"|UserPwd:"+UserPwd+"|Gender:"+Gender; } } }
這裏我重寫了ToString方法,以便待會兒更直觀的看到效果.
接下來創建EUserInfo實體類對應的table,sql如下:
use master go if exists (select * from sys.databases where name=‘reflectDemoDB‘) drop database reflectDemoDB create database reflectDemoDB go use reflectDemoDB go createtable UserInfo( UserId int primary key identity, UserCode varchar(20) not null, UserName varchar(20) not null, UserPwd varchar(20) not null, Gender char(2) check(Gender in (‘男‘,‘女‘)) ) go insert into UserInfo values(‘111111111‘,‘我體會過你的不完美。‘,‘123‘,‘男‘) insert into UserInfo values(‘222222222‘,‘寂寞陪伴著‘,‘123‘,‘男‘) insert into UserInfo values(‘333333333‘,‘偏執的眼眸︼╯‘,‘123‘,‘男‘)
為了可以方便操作ado對象我這裏寫了一個工具類DBHelper,代碼如下:
using System; using System.Collections.Generic; using System.Web; using System.Data.SqlClient; using System.Data; using System.Configuration; namespace Test { /// <summary> ///DBHelper:數據庫訪問操作類 /// </summary> public class DBHelper { /// <summary> /// 更新操作:增,刪,改 共用 /// </summary> /// <param name="sql"></param> /// <returns>bool</returns> public static bool UpdateOpera(string sql,params SqlParameter[] sps) { SqlCommand cmd = new SqlCommand(sql, Connection); //////////////////將配置參數加入到Command中 cmd.Parameters.AddRange(sps); ///////////////// return cmd.ExecuteNonQuery() > 0; } /// <summary> /// 單個查詢操作:返回首行首列數據 /// </summary> /// <param name="sql">查詢SQL語句</param> /// <returns>object</returns> public static object GetScalar(string sql, params SqlParameter[] sps) { SqlCommand cmd = new SqlCommand(sql, Connection); //////////////////將配置參數加入到Command中 cmd.Parameters.AddRange(sps); ///////////////// return cmd.ExecuteScalar(); } /// <summary> /// 多行查詢操作:返回SqlDataReader /// </summary> /// <param name="sql">查詢SQL語句</param> /// <returns>SqlDataReader</returns> public static SqlDataReader GetReader(string sql, params SqlParameter[] sps) { SqlCommand cmd = new SqlCommand(sql, Connection); //////////////////將配置參數加入到Command中 cmd.Parameters.AddRange(sps); ///////////////// return cmd.ExecuteReader(); } /// <summary> /// 多行查詢操作:返回DataTable /// </summary> /// <param name="sql">查詢SQL語句</param> /// <returns>DataTable</returns> public static DataTable GetDataTable(string sql, params SqlParameter[] sps) { DataTable dt = new DataTable(); SqlDataAdapter dad = new SqlDataAdapter(sql, Connection); //////////////////將配置參數加入到Command中 dad.SelectCommand.Parameters.AddRange(sps); ///////////////// dad.Fill(dt); return dt; } public static List<string> GetColumnsByTableName(string tableName) { List<string> columnList = new List<string>(); string sql = "select name from syscolumns where id=object_id(@tableName)"; SqlDataReader sdr = GetReader(sql, new SqlParameter("@tableName", tableName)); while (sdr.Read()) { columnList.Add(sdr["name"].ToString()); } sdr.Close(); return columnList; } private static SqlConnection _connection; /// <summary> /// Connection對象 /// </summary> public static SqlConnection Connection { get { string connectionString = "Data Source=.;Initial Catalog=reflectDemoDB;Integrated Security=True"; if (_connection == null) { _connection = new SqlConnection(connectionString); _connection.Open(); } else if (_connection.State == ConnectionState.Closed) { _connection.Open(); } else if (_connection.State == ConnectionState.Broken || _connection.State == ConnectionState.Open) { _connection.Close(); _connection.Open(); } return _connection; } } } }
接下來就可以進入主題了,我這裏是用一個BaseDao做例子,代碼如下:
using System; using System.Collections.Generic; using System.Data.SqlClient; using System.Linq; using System.Reflection; using System.Text; using System.Threading.Tasks; namespace Test { public class BaseDao<T> { /// <summary> /// 獲取泛型對應的實體類類名當做表名 /// </summary> private static string TableName { get { return typeof(T).Name.Replace("E",""); } } /// <summary> /// 獲取泛型對應實體類所有屬性 /// </summary> private static PropertyInfo[] Properties { get { return typeof(T).GetProperties(); } } /// <summary> /// 通用查詢所有方法 /// </summary> /// <returns></returns> public List<T> GetAll() { //根據獲取的表名拼裝出sql語句 string sql = "select * from " + TableName; SqlDataReader sdr = DBHelper.GetReader(sql); return CreateInstanceListOfSqlDataReader<T>(sdr); } private static T CreateInstance<T>(SqlDataReader sdr) { //或許泛型類所有屬性 //根據泛型T創建它的實例 T t = (T)Activator.CreateInstance(typeof(T)); //遍歷該類所有屬性 foreach (PropertyInfo pro in Properties) { //判斷屬性類型 如果是對應類型就強轉進行賦值 if (pro.PropertyType.Equals(typeof(DateTime))) try { pro.SetValue(t, Convert.ToDateTime(sdr[pro.Name]));//利用遊標根據屬性名獲取對應列值給屬性賦值 } catch (Exception) { throw new Exception("轉換DateTime類型失敗,[" + pro.Name + "]字段[value=" + sdr[pro.Name].ToString() + "]格式不正確"); } else if (pro.PropertyType.Equals(typeof(int))) try { pro.SetValue(t, Convert.ToInt32(sdr[pro.Name])); } catch (Exception) { throw new Exception("轉換int類型失敗,[" + pro.Name + "]字段[value=" + sdr[pro.Name].ToString() + "]格式不正確"); } else if (pro.PropertyType.Equals(typeof(double))) try { pro.SetValue(t, Convert.ToDouble(sdr[pro.Name])); } catch (Exception) { throw new Exception("轉換Double類型失敗,[" + pro.Name + "]字段[value=" + sdr[pro.Name].ToString() + "]格式不正確"); } else pro.SetValue(t, sdr[pro.Name]); } return t; } /// <summary> /// 根據遊標sdr創建一個所傳類型對象集合並返回 /// </summary> /// <typeparam name="T">泛型類型</typeparam> /// <param name="sdr">遊標</param> /// <returns></returns> private List<T> CreateInstanceListOfSqlDataReader<T>(SqlDataReader sdr) { List<T> tList = new List<T>(); while (sdr.Read()) { T t = CreateInstance<T>(sdr); tList.Add(t); } return tList; } } }
BaseDao寫好以後我們就可以看看效果了,接下來我們創建一個UserInfoDao,來繼承BaseDao,代碼如下:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Test { public class UserInfoDao:BaseDao<EUserInfo>{} }
然後我們就可以開始測試了,下面是測試代碼:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Test { class Program { static void Main(string[] args) { UserInfoDao userInfoDao = new UserInfoDao(); List<EUserInfo> userInfoList = userInfoDao.GetAll(); foreach (EUserInfo userInfo in userInfoList) { Console.WriteLine(userInfo); } Console.ReadKey(); } } }
這裏我們可以直接調用BaseDao的GetAll方法,sql會自動在BaseDao中幫我們拼裝好,得到的結果如下:
這裏我們可以看見的效果是BaseDao幫我們把數據庫中表的數據封裝到了對象中.不需要我們手動的來進行實例化賦值,希望這個Demo能對初學反射的有點啟發,有什麽不足之處大家多多指教.
反射入門-淺談反射用途_根據Ado遊標對象創建list集合