自定义ORMapping—关系表转换为实体或实体集合对象

概述

       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 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 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 ORMapping = new ORMapping();
PersonBaseCollection personBaseCollection = new PersonBaseCollection();
ORMapping.DataViewToCollection(personBaseCollection);

实现的大概思路

       DataTable转换为实体集合对象,要想完成这个功能,必须将DataTable里的每个Row的每个cell的值,赋值给实体集合对象里的具体对象的具体属性上,对于上面说的坏的效果,我们可以非常简单的实现,但是,那种方式却是不可行的(具体不说了)。

        对于上面好的效果是如何实现的呢?这个实现运用的知识为特性和反射,通过在实体类上使用自定义的特性,我们可以在程序运行的时候,通过反射,获得相应对象的所有信息,通过获取自定义的特性,我们可以得到,对象里属性和相应表中的字段的对象关系,通过反射,我们可以获得对象属性的类型,然后在进行相应的转换。

       自定义特性类(实现类内属性和表的字段名的对应关系),实体类上应用自定义的特性,通过反射,获得实体对象的所有信息,取自定义特性信息,并实现表和对象的字段和属性的相互转换。

总结

        自定义的ROMapping还差自动生成SQL这块功能,对于这块的实现,自己不是很清楚,相信会有清楚的那天,另外,LinQ的总结也欠着大家一些东西,因为这块的Demo还没有实现,后期也会补上相应的内容。

你可能感兴趣的:(C#)