C#根據(jù)反射和特性實現(xiàn)ORM映射實例分析
本文實例講述了C#根據(jù)反射和特性實現(xiàn)ORM 映射的方法。分享給大家供大家參考。具體如下:
(一)關于反射
什么是反射?
反射就是在運行時,動態(tài)獲取對象信息的方法。比如:運行時獲得對象有哪些屬性,方法,委托等。
反射的作用?
能夠?qū)崿F(xiàn)運行時,動態(tài)調(diào)用對象的方法,以及動態(tài)設置、獲取屬性值等。
反射的示例:
using System; using System.Reflection; namespace CS_Test { public class MyStudent { private string sName; public string SName { get { return sName; } set { sName = value; } } private int sAge; public int SAge { get { return sAge; } set { sAge = value; } } } class Test_Attribute { [STAThread] static void Main(string[] args) { MyStudent stu1 = new MyStudent(); stu1.SName = "劉德華"; stu1.SAge = 40; // 獲得所有屬性 PropertyInfo[] pros = stu1.GetType().GetProperties(); // 顯示所有屬性值 foreach (PropertyInfo pro in pros) Console.WriteLine(pro.Name+":"+pro.GetValue(stu1,null)); //更改stu1對象的SAge值 stu1.GetType().GetProperty("SAge").SetValue(stu1, 30, null); // 顯示所有屬性值 foreach (PropertyInfo pro in pros) Console.WriteLine(pro.Name+":"+pro.GetValue(stu1, null)); } } }
(二)關于特性
什么是 Attribute?
它是對運行時的對象或?qū)ο蟮膶傩浴⒎椒ā⑽械冗M行描述的類。
Attribute 的作用?
用于在運行時,描述你的代碼或者影響你的程序的行為。
注意:
既然Attribute 是類,那么它的定義與定義類一樣。
唯一不同的就是,自定義Attribute 類必須繼承于System.Attribute 空間。
特性的示例:
//描述數(shù)據(jù)庫字段的 Attribute public class DataFieldAttribute : Attribute { public DataFieldAttribute(string fieldName,string fieldType) { this._fieldName = fieldName; this._fieldType = fieldType; } // 數(shù)據(jù)庫字段名 private string _fieldName; public string FieldName { get { return _fieldName; } set { _fieldName = value; } } // 數(shù)據(jù)庫字段類型 private string _fieldType; public string FieldType { get { return _fieldType; } set { _fieldType = value; } } }
通過自定義Attribute,我們定義了類屬性和數(shù)據(jù)庫字段的一一對應關系,于是對MyStudent 類的Name、Age 屬性都加上Attribute 的描述,指定他們對應的數(shù)據(jù)庫字段名以及類型。
代碼更改如下:
public class MyStudent { private string _name; //使用“特性”描述對應的數(shù)據(jù)庫字段名、類型 [DataFieldAttribute("SName", "varchar")] public string Name { get { return _name; } set { _name = value; } } private int _age; [DataFieldAttribute("SAge", "int")] public int Age { get { return _age; } set { _age = value; } } }
(三)ORM 映射規(guī)則的定義
給實體類增加DataFieldAttribute 的描述,其實就是增加了O(對象)/ R(關系數(shù)據(jù)庫)的映射規(guī)則。
下面我們就通過反射的方法實現(xiàn):在運行時動態(tài)獲取O/R Mapping 的映射規(guī)則:
static void Main(string[] args) { MyStudent stu1 = new MyStudent(); stu1.Name = "劉德華"; stu1.Age = 40; //通過反射的方法來動態(tài)獲取此映射規(guī)則 PropertyInfo[] infos = stu1.GetType().GetProperties(); object[] objs_fieldAttr = null; foreach (PropertyInfo info in infos) { // GetCustomAttributes: // 返回實體對象中每個屬性對應的“特性”信息(數(shù)據(jù)庫字段名、類型) objs_fieldAttr = info.GetCustomAttributes( typeof(DataFieldAttribute), false); if (objs_fieldAttr != null) { Console.Write("實體類的屬性名:" + info.Name); Console.Write(" -> 數(shù)據(jù)庫字段名:"); Console.WriteLine(((DataFieldAttribute)objs_fieldAttr[0]).FieldName); } } }
顯示結(jié)果:
實體類的屬性名:Name -> 數(shù)據(jù)庫字段名:SName
實體類的屬性名:Age -> 數(shù)據(jù)庫字段名:SAge
接下來的工作就是:怎樣根據(jù)這種方法動態(tài)地從對象中獲取映射規(guī)則,然后動態(tài)構造Insert、Update、Delete 等 SQL 語句。這就是實現(xiàn)自己的ORM 的原理。
這里的代碼僅僅是舉例,而要真正實現(xiàn)一個ORM,我們還需要考慮的很多,比如:
1、實體類對應于哪張數(shù)據(jù)庫表?
2、數(shù)據(jù)庫表中的 PK 和 FK(如果有的話)怎么表示?
完整代碼如下:
using System; using System.Reflection; namespace CS_Test { public class MyStudent { private string _name; //使用“特性”描述對應的數(shù)據(jù)庫字段名、類型 [DataFieldAttribute("SName", "varchar")] public string Name { get { return _name; } set { _name = value; } } private int _age; [DataFieldAttribute("SAge", "int")] public int Age { get { return _age; } set { _age = value; } } } //描述數(shù)據(jù)庫字段的 Attribute public class DataFieldAttribute : Attribute { public DataFieldAttribute(string fieldName,string fieldType) { this._fieldName = fieldName; this._fieldType = fieldType; } // 數(shù)據(jù)庫字段名 private string _fieldName; public string FieldName { get { return _fieldName; } set { _fieldName = value; } } // 數(shù)據(jù)庫字段類型 private string _fieldType; public string FieldType { get { return _fieldType; } set { _fieldType = value; } } } class Test_Attribute { [STAThread] static void Main(string[] args) { MyStudent stu1 = new MyStudent(); stu1.Name = "劉德華"; stu1.Age = 40; // 獲得所有屬性 PropertyInfo[] pros = stu1.GetType().GetProperties(); // 顯示所有屬性值 foreach (PropertyInfo pro in pros) Console.WriteLine(pro.Name+":"+pro.GetValue(stu1,null)); //更改stu1對象的SAge值 stu1.GetType().GetProperty("Age").SetValue(stu1, 30, null); // 顯示所有屬性值 foreach (PropertyInfo pro in pros) Console.WriteLine(pro.Name+":"+pro.GetValue(stu1, null)); //通過反射的方法來動態(tài)獲取此映射規(guī)則 PropertyInfo[] infos = stu1.GetType().GetProperties(); object[] objs_fieldAttr = null; foreach (PropertyInfo info in infos) { // GetCustomAttributes: // 返回實體中每個屬性對應的“特性”信息(數(shù)據(jù)庫字段名、類型) objs_fieldAttr = info.GetCustomAttributes( typeof(DataFieldAttribute), false); if (objs_fieldAttr != null) { Console.Write("實體類的屬性名:" + info.Name); Console.Write(" -> 數(shù)據(jù)庫字段名:"); Console.WriteLine(((DataFieldAttribute)objs_fieldAttr[0]).FieldName); } } } } }
希望本文所述對大家的C#程序設計有所幫助。
相關文章
使用GetInvalidFileNameCharts生成文件名
這篇文章主要介紹了一個很實用的函數(shù)Path.GetInvalidFileNameCharts(),他可以很方便的生成一個有效的文件名稱2014-01-01講解.NET環(huán)境下繪制模糊數(shù)學中隸屬函數(shù)分布圖
講解.NET環(huán)境下繪制模糊數(shù)學中隸屬函數(shù)分布圖...2007-11-11C#中Write()和WriteLine()的區(qū)別分析
這篇文章主要介紹了C#中Write()和WriteLine()的區(qū)別分析,需要的朋友可以參考下2020-11-11c#創(chuàng)建windows服務(Windows Services)詳細步驟
這篇文章主要介紹了c#創(chuàng)建windows服務(Windows Services)詳細步驟,大家參考使用吧2013-12-12VSCode調(diào)試C#程序及附缺失.dll文件的解決辦法
這篇文章主要介紹了VSCode調(diào)試C#程序及附缺失.dll文件的解決辦法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-09-09