java实体类中有枚举类型_实体类的枚举属性--原来支持枚举类型这么简单,没有EF5.0也可以...

通常,我们都是在业务层和界面层使用枚举类型,这能够为我们编程带来便利,但在数据访问层,不使用枚举类型,因为很多数据库都不支持,比如我们现在用的SqlServer2008就不支持枚举类型的列,用的时候也是将枚举类型转换成int 类型,数据库存储的是int 类型的数据,在访问数据的时候进行枚举类型和int类型的转换,例如下面的例子:

public enumRoleNames

{

User,

Manager,

Admin

}

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

//获取一个实体类:

Users user=newUsers();

user.ID=1;if(EntityQuery.Fill(user))

{

RoleNames rn=(RoleNames)user.RoleID;

Console.Write("Role Name:"+rn);

}//更新实体类:

Users user=newUsers();

user.ID=1;

user.RoleID=(int)RoleNames.Admin;

EntityQuery.Instance.Update(user);

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

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

修改下Users类型的定义:

public partial classUsers : EntityBase

{//其它部分定义略

publicRoleNames RoleID

{get { return getProperty("RoleID"); }set { setProperty("RoleID", value); }

}

}

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

//更新实体类:

Users user=newUsers();

user.ID=1;

user.RoleID=RoleNames.Admin;

EntityQuery.Instance.Update(user);

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

//获取一个实体类:

Users user=newUsers();

user.ID=1;if(EntityQuery.Fill(user))

{

RoleNames rn=user.RoleID;

Console.Write("Role Name:"+rn);

}

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

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

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

public static T ChangeType(objectValue)

{if (Value isT)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));

}

}

使用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下使用。

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

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

usingSystem;usingSystem.Collections.Generic;//using System.Linq;

usingSystem.Text;usingPWMIS.DataMap.Entity;usingPWMIS.Common;namespaceOQLTest

{public enumRoleNames

{

User,

Manager,

Admin

}public partial classUsers : EntityBase

{publicUsers()

{

TableName= "LT_Users";

EntityMap=EntityMapType.Table;//IdentityName = "标识字段名";

IdentityName = "ID";//PrimaryKeys.Add("主键字段名");

PrimaryKeys.Add("ID");

}protected override voidSetFieldNames()

{

PropertyNames= new string[] { "ID", "UserName", "Password", "NickName", "RoleID", "Authority", "IsEnable", "LastLoginTime", "LastLoginIP", "Remarks", "AddTime"};

}///

///

///

publicSystem.Int32 ID

{get { return getProperty("ID"); }set { setProperty("ID", value); }

}///

///

///

publicSystem.String UserName

{get { return getProperty("UserName"); }set { setProperty("UserName", value, 50); }

}///

///

///

publicSystem.String Password

{get { return getProperty("Password"); }set { setProperty("Password", value, 50); }

}///

///

///

publicSystem.String NickName

{get { return getProperty("NickName"); }set { setProperty("NickName", value, 50); }

}///

///

///

publicRoleNames RoleID

{get { return getProperty("RoleID"); }set { setProperty("RoleID", value); }

}//用下面的方式处理实体类的子实体类问题

UserRoles _roles;publicUserRoles Roles

{get{if (_roles == null)

{

_roles= new UserRoles() { ID = this.RoleID };

EntityQuery.Fill(_roles);

}return_roles;

}

}///

///

///

publicSystem.String Authority

{get { return getProperty("Authority"); }set { setProperty("Authority", value, 250); }

}///

///

///

publicSystem.Boolean IsEnable

{get { return getProperty("IsEnable"); }set { setProperty("IsEnable", value); }

}///

///

///

publicSystem.DateTime LastLoginTime

{get { return getProperty("LastLoginTime"); }set { setProperty("LastLoginTime", value); }

}///

///

///

publicSystem.String LastLoginIP

{get { return getProperty("LastLoginIP"); }set { setProperty("LastLoginIP", value, 20); }

}///

///

///

publicSystem.String Remarks

{get { return getProperty("Remarks"); }set { setProperty("Remarks", value, 150); }

}///

///

///

publicSystem.DateTime AddTime

{get { return getProperty("AddTime"); }set { setProperty("AddTime", value); }

}

}

}

用户实体类定义

测试程序:

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.QueryList(q0);if (userList.Count > 0)

{

Users u= userList[0];

Console.WriteLine("User Type is:"+u.RoleID.ToString());

u.RoleID=RoleNames.User;

EntityQuery.Instance.Update(u);

}

程序输出:

c7db31a7fdfb645b93d2fa52664e9b7b.png

数据库结果界面:

1d9250d0f11f96702b6af9ddb304da52.png

--------------分界线----------------------

PDF.NET 开发框架是国产的开发框架,支持SQL-MAP、ORM和数据控件 三种编程模型,可以一种或者三种混合使用,是开源的开发框架,供广大.net开发朋友在EF,NH之外,提供第三中选择。欢迎加入PDF.NET开源技术团队。

相关链接:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值