当业务对象和数据库表对不上的时候,常见的现象就是字段读不出来、保存操作报错,或者系统升级以后程序直接启动不了。要把DevExpress XPO里的对象映射弄清楚,以及碰到表结构不同步该怎么处理,核心是先确定是以代码模型为基准,还是以现有数据库为基准,然后再决定是手工去配映射、靠设计器自动同步,还是跑迁移脚本。XPO可以把持久化类映射到数据表,也会根据配置去检查或者扩展数据库的结构。
一、DevExpress XPO怎么做对象映射
做对象映射得从表名、主键和字段这些最基础的地方开始。接一个已有的数据库,不能光是建一个名字一样的类,还得把主键、列名,还有表之间的关系都核对准了。
1、确定持久化对象
通常让业务类去继承XPObject或者XPLiteObject这类基类。接入旧表时,表里必须有一个能被识别的主键;已经有很多表的话,可以用Data Model Wizard去选表和列,让它自动生成对应的持久化类。
2、映射表名和列名
类名如果跟表名不一致,就在类上用PersistentAttribute标出目标表名。属性名跟列名对不上,就用PersistentAttribute里的MapTo去指定真实的列名。如果要跨Schema访问,可以把Schema名字和表名写在一块儿,但要保证目标Schema已经存在。
3、区分哪些属性要存盘
不需要往数据库里写的类或者属性,加上NonPersistentAttribute排除掉就行。页面上用来展示的计算字段,可以用PersistentAliasAttribute,按已有字段的表达式去生成,别为了展示方便就往库里多建列。
4、补齐对象关系
一对多、一对一和多对多都得按照真实的表结构来配。关联配置要是不完整,可能单表查询没问题,一到保存关联对象或者加载集合的时候,毛病就暴露了。
二、DevExpress XPO表结构不同步怎么处理
表结构不同步的时候,先得确认差异是什么类型,因为新增表、新增列,还有复杂的表结构改动,不能混在一起来处理。XPO能自己补上部分结构,但不会替你包办所有的数据库迁移。
1、开发环境选好运行模式
初始化Data Layer时,用AutoCreateOption.DatabaseAndSchema可以试着建库并更新结构;用SchemaOnly就只更新已有的库;None模式不改数据库,但仍然会查结构是不是兼容;SchemaAlreadyExists会跳过校验,可是数据库实际不兼容的话,后面读写还是可能报错。
2、复杂变更用迁移脚本
删除或重命名类、属性之后,XPO不会自动去清掉旧表或旧列,已有的列类型、索引和外键也不会自动改写。生产环境遇到这类变动,应该先把数据库备份好,再生成迁移脚本,放到测试库里跑一遍,别让应用在启动时自己动手去改正式库。
3、从现有数据库反向同步模型
如果数据库是DBA先调好的,那就打开Data Model Designer,用【Update Model From Database】把数据库里的改动同步回对象模型。反过来,要从模型生成数据库调整脚本,就用【Generate Migration Script】。
4、检查权限和连接环境
结构更新要是失败了,还得看连接字符串对不对、数据库账号的权限够不够。经常是开发环境能跑,部署环境不行,原因就是生产账号往往只有读写权限,没有建表或改结构的权限。
三、DevExpress XPO结构调整后怎么复核
结构同步完以后,不能只看程序能启动就算数,还得再做一次映射、数据和版本的复核。
1、检查关键表和系统字段
看看新增的表、列和关联表是不是都生成了。如果用了继承、软删除或者乐观锁,XPO还可能自动加上XPObjectType、GCRecord、OptimisticLockField这类辅助字段。
2、跑一遍基础读写
挑几个关键对象,依次试试新增、查询、修改和删除操作,再顺便加载一下关联集合。很多映射错误,只查列表页是看不出来的,得等到保存或者关联操作的时候才会暴露。
3、对比测试库和生产库
上线前把两套库的结构清单导出来,去对表名、列名、类型、主键、索引和外键。旧列要不要保留,也应当在迁移记录里写清楚。
4、固定迁移流程
把模型变更、迁移脚本、数据库备份、执行顺序和回滚方案都放到发布清单里。以后再增加字段或者拆分表,就跟着同一套流程来走。
总结
DevExpress XPO的对象映射和表结构同步,顺序就是先确定好持久化类、表名、列名和关系,再视环境决定用自动检查、自动扩展还是迁移脚本。开发环境能靠AutoCreateOption快速验证,生产环境碰到重命名、删列和类型调整时,就要靠验证过的迁移脚本来处理。最后再做一遍基础读写和结构对比,这样才算真正把表结构同步做完了。
