標籤:style blog 使用 資料 2014 os
概述
ORMapping,中文翻譯過來就是,關聯性物件的映射,他的作用就是使我們編程時,不用過多的關注持久層,只需要關注對象,關注業務就可以了。ORMapping主要完成兩個功能:自動產生SQL語句和DataTable To Objects。
特性和反射
特性是用來描述中繼資料的,中繼資料就是原始碼編譯好後的代碼。反射是運行時,獲得對象或類的所有資訊,通過這些資訊,我們可以建立類獲得特性資訊等等
關係錶轉換為實體或實體集合對象的實現方式
對於關係錶轉換為實體或實體集合對象的實現方法可以有多種,這裡說一下比較極端的兩種。
關係錶轉換為實體集合,壞效果的方式是,針對於每個實體集合類型,我們建立一個類來實現相應關係和實體的轉化,好效果的方式是,建立一個類,這個類實現所有實體集合類型的DataTable的轉換,對於坏的方式這裡不再提供代碼,對於好的方式,提供如下代碼。大家可以看看裡面的實現。
自訂屬性類別
using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace 集合.集合.自訂特性{ [AttributeUsage(AttributeTargets.Property,AllowMultiple=true,Inherited=false)] public class ORMappingFieldAttribute:Attribute { private string _strFieldName; public ORMappingFieldAttribute(string _strFieldName) { this._strFieldName = _strFieldName; } public string strFieldName { get { return _strFieldName; } } }}
實體類
using System;using System.Collections.Generic;using System.Linq;using System.Text;using 集合.集合.自訂特性;namespace TableToCollection.實體{ [ORMappingTable("T_Person")] public class Person { [ORMappingField("id")] public string strID { get; set; } [ORMappingField("name")] public string strName { get; set; } [ORMappingField("age")] public int intAge { get; set; } }}
關聯性物件轉換類
using System;using System.Collections.Generic;using System.Linq;using System.Text;using 集合.資料庫訪問;using 集合.集合.靈活性好的集合;using System.Reflection;using System.Data;using 集合.集合.自訂特性;namespace 集合.ORMapping.ORMapping{ public class ORMapping<T> where T:new() { private DataTable dt; public ORMapping() { dt = new DataTable(); } public void GetDataTable() { PersonDLL personDLL = new PersonDLL(); dt = personDLL.Query(); } public void DataRowToTObject(T TObject,DataRow dr) { //得到entity類型 Type type = TObject.GetType(); //取得T類型的所有公用屬性 PropertyInfo[] allPropertyInfo = type.GetProperties(); foreach (PropertyInfo item in allPropertyInfo) { //返回屬性的自訂ORMappingFieldAttribute的所有特性 object[] propertyCustomAttributes = item.GetCustomAttributes(typeof(ORMappingFieldAttribute), false); foreach (ORMappingFieldAttribute attribute in propertyCustomAttributes) { if (dt.Columns.Contains(attribute.strFieldName)) { object TObjectPropertyValue = dr[attribute.strFieldName]; if (TObjectPropertyValue == DBNull.Value) { continue; } #region 類型轉化 if (item.PropertyType.Equals(typeof(string))) { TObjectPropertyValue = dr[attribute.strFieldName].ToString(); } else if (item.PropertyType.Equals(typeof(int))) { TObjectPropertyValue = Convert.ToInt32(dr[attribute.strFieldName]); } else if (item.PropertyType.Equals(typeof(decimal))) { TObjectPropertyValue = Convert.ToDecimal(dr[attribute.strFieldName]); } else if (item.PropertyType.Equals(typeof(DateTime))) { TObjectPropertyValue = Convert.ToDateTime(dr[attribute.strFieldName]); } else if (item.PropertyType.Equals(typeof(double))) { TObjectPropertyValue = Convert.ToDouble(dr[attribute.strFieldName]); } else if (item.PropertyType.Equals(typeof(bool))) { TObjectPropertyValue = Convert.ToBoolean(dr[attribute.strFieldName]); } ///利用反射自動將value賦值給obj的相應公用屬性 item.SetValue(TObject, TObjectPropertyValue, null); #endregion } } } } public void DataViewToCollection(BaseCollection<T> TCollection) { GetDataTable(); for (int i = 0; i < dt.Rows.Count; i++) { T TObject = new T(); DataRowToTObject(TObject, dt.Rows[i]); TCollection.Add(TObject); } } }} main函數裡的核心代碼
ORMapping<Person> ORMapping = new ORMapping<Person>();PersonBaseCollection personBaseCollection = new PersonBaseCollection();ORMapping.DataViewToCollection(personBaseCollection);
實現的大概思路
DataTable轉換為實體集合對象,要想完成這個功能,必須將DataTable裡的每個Row的每個cell的值,賦值給實體集合對象裡的具體對象的具體屬性上,對於上面說的壞的效果,我們可以非常簡單的實現,但是,那種方式卻是不可行的(具體不說了)。
對於上面好的效果是如何?的呢?這個實現運用的知識為特性和反射,通過在實體類上使用自訂的特性,我們可以在程式啟動並執行時候,通過反射,獲得相應對象的所有資訊,通過擷取自訂的特性,我們可以得到,對象裡屬性和相應表中的欄位的對象關係,通過反射,我們可以獲得對象屬性的類型,然後在進行相應的轉換。
自訂屬性類別(實作類別內屬性和表的欄位名的對應關係),實體類上應用自訂的特性,通過反射,獲得實體物件的所有資訊,取自訂特性資訊,並實現表和對象的欄位和屬性的相互轉換。
總結
自訂的ROMapping還差自動產生SQL這塊功能,對於這塊的實現,自己不是很清楚,相信會有清楚的那天,另外,LinQ的總結也欠著大家一些東西,因為這塊的Demo還沒有實現,後期也會補上相應的內容。