public enum RoleNames
    { 
        User,
        Manager,
        Admin
    }


假设有一个实体类Users,如果实体类不支持枚举类型,得这样使用(下面的示例都以PDF.NET的ORM框架使用来说明):


mysql枚举值比较 sql枚举查询_实体类



//获取一个实体类:
Users user=new Users();
user.ID=1;

if(EntityQuery<Users>.Fill(user))
{
 RoleNames rn=(RoleNames)user.RoleID;
 Console.Write("Role Name:"+rn);
}


//更新实体类:
Users user=new Users();
user.ID=1;
user.RoleID=(int)RoleNames.Admin;
EntityQuery<Users>.Instance.Update(user);



mysql枚举值比较 sql枚举查询_实体类


    查询和更新操作都得对枚举类型进行转换,不方便,虽然如此,我们大部分情况下还是将就了,在访问数据库的时候这么转换下。这种情况下EF 5.0 之前也不例外,都是社区用户的强烈要求,在EF5.0版本之后才加入支持实体类枚举属性的。

    既然使用枚举还要将实体类的属性转换下,为何不直接将实体类的属性定义成枚举类型?
    修改下Users类型的定义:


mysql枚举值比较 sql枚举查询_实体类



public partial class Users : EntityBase
{
        //其它部分定义略

        public RoleNames RoleID
        {
            get { return getProperty<RoleNames>("RoleID"); }
            set { setProperty("RoleID", value); }
        }

}



mysql枚举值比较 sql枚举查询_实体类


直接使用这个修改过的实体类来插入、修改数据,是没有问题的:


//更新实体类:
Users user=new Users();
user.ID=1;
user.RoleID=RoleNames.Admin;
EntityQuery<Users>.Instance.Update(user);


但是查询实体类的时候会有点小问题,虽然能够正确的从数据库查询,但查看枚举属性的时候会报类型转换错误:


mysql枚举值比较 sql枚举查询_实体类



//获取一个实体类:
Users user=new Users();
user.ID=1;

if(EntityQuery<Users>.Fill(user))
{
 RoleNames rn=user.RoleID;
 Console.Write("Role Name:"+rn);
}



mysql枚举值比较 sql枚举查询_实体类


    跟踪代码发现,user.RoleID 对应的SqlReader 的结果类型是int ,因为数据库的RoleID 列没法定义成枚举类型,如果要将实体类的属性定义成枚举类型,那么在SqlReader读取的时候,必须进行类型转换:


user.RoleID=(RoleNames)reader["RoleID"];


    幸好PDF.NET的实体类认为“实体类是数据的容器”,内部采用一个object[] 保存来自数据库的原始数据,而在使用数据的时候,才来进行类型转换,因此框架原来查询数据、插入、更新数据的地方,都不用做任何修改,只需要修改下 getProperty<T>("fieldName") 涉及的部分:


mysql枚举值比较 sql枚举查询_实体类



public static T ChangeType<T>(object Value)
       {
           if (Value is T)
               return (T)Value;
           else if (Value == DBNull.Value || Value == null)
           {
               if (typeof(T) == typeof(DateTime))
               {
                   //如果取日期类型的默认值 0001/01/01 ,在WCF JSON序列化的时候,会失败。
                   object o = new DateTime(1900, 1, 1);
                   return (T)o;
               }
               else
                   return default(T);
           }
           else
           {
               //edit at 2011.5.16
               //如果 Value为 decimal类型,T 为double 类型, (T)Value 将发生错误
               //edit at 2013.8.9 支持枚举类型
               if (typeof(T).IsEnum)
                   return (T)Value;
               else
                   return (T)Convert.ChangeType(Value, typeof(T));
           }
       }



mysql枚举值比较 sql枚举查询_实体类


使用PDF.NET框架的V4.X 版本(包括V4.6之前的版本)用户,只需要打开 CommonUtil.cs 文件,找到该方法,将


return (T)Convert.ChangeType(Value, typeof(T));


修改为:


if (typeof(T).IsEnum)
       return (T)Value;
 else
       return (T)Convert.ChangeType(Value, typeof(T));


即可。

    经过测试,通过这样的修改,框架就可以支持实体类使用枚举类型了。

    为什么修改如此简单?前面已经说过,PDF.NET的实体类是数据的容器,也就是说,我们在内存中将某个属性的值直接设置为枚举类型的值,也可以将内存中的Int 类型的来自数据库的值,在运行时转换成枚举类型。这样,使得PDF.NET的实体类的属性类型可以不必跟数据库的字段类型严格对应,只要类型相容即可。这个特点为系统移植数据库平台提供了很大的便利,比如Oracle 没有Decimal类型,没有real 类型,要使用非整形的数字类型,只有使用Number类型,那么为SqlServer设计使用的实体类,一般情况下也可以直接在Oracle下使用。

    下面的代码是一个完整的使用实体类的枚举属性的例子:




mysql枚举值比较 sql枚举查询_实体类_09

用户实体类定义

    测试程序:


mysql枚举值比较 sql枚举查询_实体类


Users user = new Users() { NickName = "pdf.net", RoleID= RoleNames.Admin };
         
            OQL q0 = OQL.From(user)
               .Select()
               .Where(user.NickName, user.RoleID) 
               .OrderBy(user.ID)
               .END;
            q0.SelectStar = true;
            Console.WriteLine("q0:one table and select all fields \r\n{0}", q0);
            Console.WriteLine(q0.PrintParameterInfo());

            var userList= EntityQuery<Users>.QueryList(q0);
            if (userList.Count > 0)
            {
                Users u = userList[0];
                Console.WriteLine("User Type is:"+u.RoleID.ToString());
                u.RoleID = RoleNames.User;
                EntityQuery<Users>.Instance.Update(u);
            }


mysql枚举值比较 sql枚举查询_实体类


    程序输出:

mysql枚举值比较 sql枚举查询_枚举类型_12

 

 

    数据库结果界面:

mysql枚举值比较 sql枚举查询_实体类_13