博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
实体类的枚举属性--原来支持枚举类型这么简单,没有EF5.0也可以
阅读量:7071 次
发布时间:2019-06-28

本文共 4021 字,大约阅读时间需要 13 分钟。

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

public enum RoleNames    {         User,        Manager,        Admin    }

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

//获取一个实体类:Users user=new Users();user.ID=1;if(EntityQuery
.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
.Instance.Update(user);

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

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

    修改下Users类型的定义:

public partial class Users : EntityBase{        //其它部分定义略        public RoleNames RoleID        {            get { return getProperty
("RoleID"); } set { setProperty("RoleID", value); } }}

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

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

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

//获取一个实体类:Users user=new Users();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<T>("fieldName") 涉及的部分:

public static T ChangeType
(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)); } }

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

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

 
用户实体类定义

    测试程序:

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); }

    程序输出:

 

 

    数据库结果界面:

 

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

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

相关链接:

    本文转自深蓝医生博客园博客,原文链接:http://www.cnblogs.com/bluedoctor/p/3252963.html,如需转载请自行联系原作者
你可能感兴趣的文章
Swift 4 踩坑之 Codable 协议
查看>>
rem(移动端:用百分比,rem,和flex布局一起写)?
查看>>
RxJava2最强源码解析系列1:Observable
查看>>
拆轮子系列--RxJava理解(三)--observeOn
查看>>
HTML5离线应用与客户端存储
查看>>
基于spring boot 及mybatis的web开发环境搭建
查看>>
Android点赞控件--仿掘金点赞七成效果
查看>>
人人都能学会的python编程教程11:定义函数
查看>>
《CSDN:2019 区块链开发者报告》:Qtum 公链设计与开发细节揭秘(上篇)
查看>>
全球手机市场尽显萧条之像,国产手机厂商如何逆流而上?
查看>>
手把手教你使用Go基于zookeeper编写服务发现「原创」
查看>>
深入解析webpack 插件html-webpack-plugin
查看>>
关于Netty的一些理解、实践与陷阱
查看>>
组件化工具BeeHive(二):组件化实践
查看>>
消息队列-ActiveMQ
查看>>
AI考拉技术分享-Node基础架构专题(一)
查看>>
关于git的操作
查看>>
Linode CentOS 7 使用 Mina 部署 Rails API 项目 Postgresql 9.6 + Nginx + Puma + Rbenv
查看>>
git下载仓库指定目录
查看>>
AVL树
查看>>