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