概述
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还没有实现,后期也会补上相应的内容。