C# 通過反射初探ORM框架的實(shí)現(xiàn)原理(詳解)
背景:
以前學(xué)的Java進(jìn)行開發(fā),多用到Mybatis,Hiberante等ORM框架,最近需要上手一個(gè)C#的項(xiàng)目,由于不是特別難,也不想再去學(xué)習(xí)C#的ORM框架,所以就想著用反射簡(jiǎn)單的實(shí)現(xiàn)一下ORM框架的內(nèi)容,簡(jiǎn)單的增刪改查,沒有用到多表之間的聯(lián)系。
反射:
Java和C#中的反射大體相同,主要是指程序可以訪問,檢測(cè)和修改它本身狀態(tài)或行為的一種能力,并能根據(jù)自身行為的狀態(tài)和結(jié)果,調(diào)整或修改應(yīng)用所描述行為的狀態(tài)和相關(guān)的語義。我的理解就是可以程序運(yùn)行時(shí)動(dòng)態(tài)的獲取對(duì)象的屬性和方法,并且可以進(jìn)行與之相關(guān)的調(diào)用。
首先看一下C#中反射實(shí)現(xiàn)方式:
獲取Type對(duì)象,反射操作都需要通過Type對(duì)象來進(jìn)行。
通過全限定名來獲取 Type tp = Type.GetType("TJCommon.Dao.Deriver");
通過類來獲取 Type tp = typeof(Int)
獲取到Type對(duì)象后我們可以通過其構(gòu)造方法來創(chuàng)建對(duì)象
調(diào)用無參構(gòu)造
// 獲取類的初始化構(gòu)造信息 ConstructorInfo ct = tp.GetConstructor(System.Type.EmptyTypes); // 調(diào)用不帶參數(shù)的構(gòu)造器 T newObj = (T)ct.Invoke(null);
調(diào)用有參構(gòu)造
//定義參數(shù)類型數(shù)組 Type[] tps = new Type[2]; tps[0] = typeof(int); tps[1] = typeof(string); //獲取類的初始化參數(shù)信息 ConstructorInfo ct2 = tp.GetConstructor(tps); //定義參數(shù)數(shù)組 object[] obj = new object[2]; obj[0] = (object)100; obj[1] = (object)"Param Example"; //調(diào)用帶參數(shù)的構(gòu)造器 ExampleClass Ex2 = (ExampleClass)ct2.Invoke(obj);
獲得所有公共字段
// 獲取到所有公共字段 FieldInfo[] arr = t.GetFields(); // 給指定的字段賦值 需要傳遞進(jìn)來一個(gè)對(duì)象 newObj f.SetValue(newObj, r[name]);
這里就介紹這幾個(gè)方法,通過反射可以獲得類中的所有信息,并且可以進(jìn)行調(diào)用,還可以打破封裝(不安全)
練習(xí)
下面就是通過反射將從數(shù)據(jù)庫中獲取到的結(jié)果集自動(dòng)封裝到Bean中。無需手動(dòng)封裝
public static T dataToObj(String str)
{
String strSql = str;
DataSet ds = SqlCompose.ExecuteSqlQuery(strSql);
Type t = typeof(T);
DataRow r = ds.Tables[0].Rows[0]; // 找到一行
FieldInfo[] arr = t.GetFields(); // 返回所有公共字段(public)
ConstructorInfo ct = t.GetConstructor(System.Type.EmptyTypes);
T newObj = (T)ct.Invoke(null);
if (r != null)
{
foreach (FieldInfo f in arr)// 遍歷所有字段
{
string name = f.Name;
Type type2 = f.FieldType;
if (r[name].GetType() != typeof(DBNull))
{
string typeName = f.FieldType.Name;
f.SetValue(newObj, r[name]);
}
}
}
else
{
newObj = default(T);
}
ds.Tables.Clear();
return newObj;
}
封裝到List
public static List<T> dataToList(String str)
{
List<T> list = new List<T>();
String strSql = str;
DataSet ds = SqlCompose.ExecuteSqlQuery(strSql);
Type t = typeof(T);
FieldInfo[] arr = t.GetFields(); // 返回所有公共字段(public)
ConstructorInfo ct = t.GetConstructor(System.Type.EmptyTypes);
foreach (DataRow dr in ds.Tables[0].Rows)
{
T newObj = (T)ct.Invoke(null);
foreach (FieldInfo f in arr)// 遍歷所有字段
{
string name = f.Name;
Type type2 = f.FieldType;
string typeName = f.FieldType.Name;
if (dr[name].GetType() != typeof(DBNull))
{
f.SetValue(newObj, dr[name]);
}
}
list.Add(newObj);
}
ds.Tables.Clear();
return list;
}
拼接字符串進(jìn)行insert操作
public static void inserByBean(string tableName, T target)
{
StringBuilder sql = new StringBuilder(); // 拼接的sql
sql.Append("insert into "+tableName+"(");
Type t = target.GetType();
PropertyInfo[] ps = t.GetProperties();
for (int i = 0; i < ps.Length; i++)
{
object obj = ps[i].GetValue(target, null);
if (obj != null)
{
string name = ps[i].Name;
if (i != ps.Length - 1)
{
sql.Append(" " + name + ",");
}
else
{
sql.Append(" " + name + "");
}
}
}
sql.Append(") values(");
for (int i = 0; i < ps.Length; i++)
{
object obj = ps[i].GetValue(target, null);
if (obj != null)
{
if (i != ps.Length - 1)
{
if (ps[i].PropertyType == typeof(string) || ps[i].PropertyType == typeof(DateTime))
{
sql.Append("'" + obj + "',");
}
else {
sql.Append("" + obj + ",");
}
}
else
{
if (ps[i].PropertyType == typeof(string) || ps[i].PropertyType == typeof(DateTime))
{
sql.Append("'" + obj + "')");
}
else
{
sql.Append("" + obj + ")");
}
}
}
}
string resultSql = sql.ToString();
SqlCompose.ExecuteSqlNonQuery(resultSql);
}
以上這篇C# 通過反射初探ORM框架的實(shí)現(xiàn)原理(詳解)就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
C#定義并實(shí)現(xiàn)單鏈表實(shí)例解析
這篇文章主要介紹了C#定義并實(shí)現(xiàn)單鏈表實(shí)例解析,有助于讀者加深對(duì)C#實(shí)現(xiàn)數(shù)據(jù)結(jié)構(gòu)的理解,需要的朋友可以參考下2014-07-07
C#彈出對(duì)話框確定或者取消執(zhí)行相應(yīng)操作的實(shí)例代碼
這篇文章主要介紹了C#彈出對(duì)話框確定或者取消執(zhí)行相應(yīng)操作的實(shí)例代碼,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-12-12
C#中將xml文件反序列化為實(shí)例時(shí)采用基類還是派生類的知識(shí)點(diǎn)討論
在本篇文章里小編給大家整理的是關(guān)于C#中將xml文件反序列化為實(shí)例時(shí)采用基類還是派生類的知識(shí)點(diǎn)討論,有需要的朋友們學(xué)習(xí)下。2019-11-11
WinForm實(shí)現(xiàn)狀態(tài)欄跑馬燈效果的方法示例
這篇文章主要介紹了WinForm實(shí)現(xiàn)狀態(tài)欄跑馬燈效果的方法,涉及WinForm控件結(jié)合時(shí)間函數(shù)動(dòng)態(tài)操作元素屬性的相關(guān)技巧,需要的朋友可以參考下2017-07-07
WPF實(shí)現(xiàn)倒計(jì)時(shí)轉(zhuǎn)場(chǎng)動(dòng)畫效果
這篇文章主要介紹了如何利用WPF實(shí)現(xiàn)倒計(jì)時(shí)轉(zhuǎn)場(chǎng)動(dòng)畫效果,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)或工作有一定幫助,需要的可以參考一下2022-08-08
C#驗(yàn)證控件validator的簡(jiǎn)單使用
這篇文章主要介紹了C#驗(yàn)證控件validator的簡(jiǎn)單使用方法和示例,十分的簡(jiǎn)單實(shí)用,有需要的小伙伴可以參考下。2015-06-06
用C#對(duì)ADO.NET數(shù)據(jù)庫完成簡(jiǎn)單操作的方法
用C#對(duì)ADO.NET數(shù)據(jù)庫完成簡(jiǎn)單操作的方法...2007-03-03

