背景: 以前學的Java進行開發,多用到Mybatis,Hiberante等ORM框架,最近需要上手一個C#的項目,由於不是特別難,也不想再去學習C#的ORM框架,所以就想著用反射簡單的實現一下ORM框架的內容,簡單的增刪改查,沒有用到多表之間的聯繫。 反射: Java和C#中的反射大體相同,主要是 ...
背景:
以前學的Java進行開發,多用到Mybatis,Hiberante等ORM框架,最近需要上手一個C#的項目,由於不是特別難,也不想再去學習C#的ORM框架,所以就想著用反射簡單的實現一下ORM框架的內容,簡單的增刪改查,沒有用到多表之間的聯繫。
反射:
Java和C#中的反射大體相同,主要是指程式可以訪問,檢測和修改它本身狀態或行為的一種能力,並能根據自身行為的狀態和結果,調整或修改應用所描述行為的狀態和相關的語義。我的理解就是可以程式運行時動態的獲取對象的屬性和方法,並且可以進行與之相關的調用。
首先看一下C#中反射實現方式:
獲取Type對象,反射操作都需要通過Type對象來進行。
1 通過全限定名來獲取 Type tp = Type.GetType("TJCommon.Dao.Deriver"); 2 3 通過類來獲取 Type tp = typeof(Int)
獲取到Type對象後我們可以通過其構造方法來創建對象
調用無參構造
1 // 獲取類的初始化構造信息 2 ConstructorInfo ct = tp.GetConstructor(System.Type.EmptyTypes); 3 // 調用不帶參數的構造器 4 T newObj = (T)ct.Invoke(null);
調用有參構造
1 //定義參數類型數組 2 Type[] tps = new Type[2]; 3 tps[0] = typeof(int); 4 tps[1] = typeof(string); 5 //獲取類的初始化參數信息 6 ConstructorInfo ct2 = tp.GetConstructor(tps); 7 8 //定義參數數組 9 object[] obj = new object[2]; 10 obj[0] = (object)100; 11 obj[1] = (object)"Param Example"; 12 13 //調用帶參數的構造器 14 ExampleClass Ex2 = (ExampleClass)ct2.Invoke(obj);
獲得所有公共欄位
1 2 // 獲取到所有公共欄位 3 FieldInfo[] arr = t.GetFields(); 4 5 // 給指定的欄位賦值 需要傳遞進來一個對象 newObj 6 f.SetValue(newObj, r[name]);
這裡就介紹這幾個方法,通過反射可以獲得類中的所有信息,並且可以進行調用,還可以打破封裝(不安全)
練習
下麵就是通過反射將從資料庫中獲取到的結果集自動封裝到Bean中。無需手動封裝
1 public static T dataToObj(String str) 2 { 3 4 String strSql = str; 5 DataSet ds = SqlCompose.ExecuteSqlQuery(strSql); 6 7 Type t = typeof(T); 8 DataRow r = ds.Tables[0].Rows[0]; // 找到一行 9 FieldInfo[] arr = t.GetFields(); // 返回所有公共欄位(public) 10 ConstructorInfo ct = t.GetConstructor(System.Type.EmptyTypes); 11 T newObj = (T)ct.Invoke(null); 12 if (r != null) 13 { 14 foreach (FieldInfo f in arr)// 遍歷所有欄位 15 { 16 string name = f.Name; 17 Type type2 = f.FieldType; 18 if (r[name].GetType() != typeof(DBNull)) 19 { 20 string typeName = f.FieldType.Name; 21 f.SetValue(newObj, r[name]); 22 } 23 } 24 } 25 else 26 { 27 newObj = default(T); 28 } 29 ds.Tables.Clear(); 30 31 return newObj; 32 }
封裝到List
1 public static List<T> dataToList(String str) 2 { 3 List<T> list = new List<T>(); 4 5 String strSql = str; 6 DataSet ds = SqlCompose.ExecuteSqlQuery(strSql); 7 8 Type t = typeof(T); 9 FieldInfo[] arr = t.GetFields(); // 返回所有公共欄位(public) 10 ConstructorInfo ct = t.GetConstructor(System.Type.EmptyTypes); 11 12 foreach (DataRow dr in ds.Tables[0].Rows) 13 { 14 T newObj = (T)ct.Invoke(null); 15 foreach (FieldInfo f in arr)// 遍歷所有欄位 16 { 17 string name = f.Name; 18 Type type2 = f.FieldType; 19 string typeName = f.FieldType.Name; 20 if (dr[name].GetType() != typeof(DBNull)) 21 { 22 f.SetValue(newObj, dr[name]); 23 } 24 25 } 26 27 list.Add(newObj); 28 29 } 30 ds.Tables.Clear(); 31 return list; 32 33 }
拼接字元串進行insert操作
1 public static void inserByBean(string tableName, T target) 2 { 3 4 StringBuilder sql = new StringBuilder(); // 拼接的sql 5 6 sql.Append("insert into "+tableName+"("); 7 8 Type t = target.GetType(); 9 PropertyInfo[] ps = t.GetProperties(); 10 11 for (int i = 0; i < ps.Length; i++) 12 { 13 14 object obj = ps[i].GetValue(target, null); 15 if (obj != null) 16 { 17 string name = ps[i].Name; 18 if (i != ps.Length - 1) 19 { 20 sql.Append(" " + name + ","); 21 } 22 else 23 { 24 sql.Append(" " + name + ""); 25 } 26 } 27 } 28 29 sql.Append(") values("); 30 31 32 for (int i = 0; i < ps.Length; i++) 33 { 34 object obj = ps[i].GetValue(target, null); 35 36 if (obj != null) 37 { 38 if (i != ps.Length - 1) 39 { 40 if (ps[i].PropertyType == typeof(string) || ps[i].PropertyType == typeof(DateTime)) 41 { 42 sql.Append("'" + obj + "',"); 43 } 44 else { 45 sql.Append("" + obj + ","); 46 } 47 } 48 else 49 { 50 if (ps[i].PropertyType == typeof(string) || ps[i].PropertyType == typeof(DateTime)) 51 { 52 sql.Append("'" + obj + "')"); 53 } 54 else 55 { 56 sql.Append("" + obj + ")"); 57 } 58 } 59 } 60 } 61 string resultSql = sql.ToString(); 62 SqlCompose.ExecuteSqlNonQuery(resultSql); 63 }