自定义ORMapping―动态生成SQL语句(一)

2015-01-27 05:59:43 · 作者: · 浏览: 16

概述

之前在自定义ORMapping――关系表转换为实体或实体集合对象中提到过ORMapping的东西,在那片博客中也有ORMapping实现的一个简单思路,当时只实现了关系表转换为实体或实体集合这个功能,没有实现动态生成SQL这个部分,本片博客就是完善之前的那片博客,实现动态生成SQL语句这么一个功能。


实现思路

1、创建两个自定义特性,分别为表特性和字段特性,目的就是给相应的实体类的类名和属性名,打上相应的特性,从而创建类名和表名,属性和表字段名之间的对应关系

2、创建一个特性解析类,用来解析,这个实体类和表之间的对应关系,即获得这种对应关系

3、创建相应常量类和枚举,常量类用来生成相应的各种运算符或者排序时的关键字,枚举用来说明,生成字段对应的value是否需要添加引号

4、创建相应的where,order生成器类,用来添加相应的条件

5、创建一个整合类,将上面说的那些东西,整个为一个整体,生成相应的SQL语句,并且执行,并将返回的DataTable转换为集合对象

下面的每块内容就是相应的实现


自定义特性类

a、自定义特性的定义

    /// 
    /// 自定义字段特性
    /// 
    [AttributeUsage(AttributeTargets.Property, AllowMultiple = true, Inherited = false)]
    public class ORFieldMappingAttribute : Attribute
    {
        /// 
        /// 属性和字段的对应
        /// 
        /// 字段名称
        /// 是否自增
        /// 有没有逗号
        public ORFieldMappingAttribute(string strFieldName, bool IsAutoIncreate = false, ORFieldValueHaveCommaEnum ORFieldValueHaveCommaEnum = ORFieldValueHaveCommaEnum.True)
        {
            this.strFieldName = strFieldName;
            this.ORFieldValueHaveCommaEnum = ORFieldValueHaveCommaEnum;
            this.IsAutoIncreate = IsAutoIncreate;
        }

        public string strFieldName { get; set; }
        public ORFieldValueHaveCommaEnum ORFieldValueHaveCommaEnum { get; set; }
        public bool IsAutoIncreate { get; set; }
    }

    /// 
    /// 自定义表特性
    /// 
    [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
    public class ORTableMappingAttribute : Attribute
    {
        /// 
        /// 类名和表明的对应
        /// 
        /// 表名
        public ORTableMappingAttribute(string strTableName)
        {
            this.strTableName = strTableName;
        }

        public string strTableName { get; set; }
    }
b、自定义特性的使用,使用在具体的一个实体类上,具体如下:

    [ORTableMapping("T_Users")]
    public  class User
    {
        [ORFieldMapping("Id",true,ORFieldValueHaveCommaEnum.False)]
        public int UserId { get; set; }

        [ORFieldMapping("Name",false,ORFieldValueHaveCommaEnum.True)]
        public string UserName { get; set; }

        [ORFieldMapping("Sex", false, ORFieldValueHaveCommaEnum.True)]
        public string UserSex { get; set; }

        [ORFieldMapping("Address", false, ORFieldValueHaveCommaEnum.True)]
        public string Addr { get; set; }

        [ORFieldMapping("Contents", false, ORFieldValueHaveCommaEnum.True)]
        public string Content { get; set; }
   }

解析自定义特性类

a、解析自定义特性类的代码如下

        ///  /// 获得实体的表名 /// 
        /// 实体的type对象
        /// 
   
    实体对象对应的表名
   
        public static string GetTableName()
        {
            T obj = new T();
            Type type = obj.GetType();

            string strTableName="";
            object[] Attarrs = type.GetCustomAttributes(false);
            for (int i = 0; i < Attarrs.Length; i++)
            {
                if (Attarrs[i] is ORTableMappingAttribute)
                {
                    ORTableMappingAttribute attribute = Attarrs[i] as ORTableMappingAttribute;
                    strTableName = attribute.strTableName;
                }
            }
            return strTableName;
        }

        ///  /// 获得实体属性对应的字段,并给字段赋值 /// 
        /// 实体的type对象
        /// 
   
    字典:key=字段名;value=字段值
   
        public static Dictionary
   
     GetFieldName(T obj) { Dictionary
    
      dic = new Dictionary
     
      (); Type type = obj.GetType(); PropertyInfo[] pis = type.GetProperties(); for (int i = 0; i < pis.Length; i++) { object[] Attarrs = pis[i].GetCustomAttributes(false); for (int j = 0; j < Attarrs.Length; j++) { if (Attarrs[j] is ORFieldMappingAttribute) { ORFieldMappingAttribute fn = Attarrs[j] as ORFieldMappingAttribute; if (fn.IsAutoIncreate != true) { if (fn.ORFieldValueHaveCommaEnum.ToString() == "True") { dic.Add(fn.strFieldName, "'" + pis[i].GetValue(obj, null).ToString() + "'"); } else { dic.Add(fn.strFieldName, pis[i].GetValue(obj, null).ToString()); } } } } } return dic; } }
     
    
   
该类是在生成SQL语句时使用的,只要你的实体类用上相应的特性,只要你把这个类型传递给这个解析类,他就可以给你解决出该类的类名和属性名,与数据库中的表名和字段名的对应关系


常量和枚举

定义如下常量和枚举类型

    ///  /// 逻辑运算符 /// 
    public class LogicOperatorConst
    {
        public const string And = "and";
        public const string Or = "or";
        public const string None = "";
    }

    ///  /// 字段的排序方向定义 /// 
    public class FieldSortConst
    {
        public const string Asc = "asc";
        public const string Desc = "desc";
    }

    ///  /// 比较运算符 /// 
    public class CompareOperationConst
    {
        //条件项的运算符常量定义
        public const string EqualTo = "=";
        public const string GreaterThanOrEqualTo = ">=";
        public const string GreaterThan = ">";
        public const string LessThanOrEqualTo = "<=";
        public const string LessThan = "<";
        public const string NotEqualTo = "<>";
        public const string Like = "LIKE";
        public const string Is = "IS";
        public const s