Ale*_*aus 6 nhibernate entity-framework devexpress xpo upgrade
使用ORM(DevExpress XPO,NHibernate或MS Entity Framework)升级数据库的最佳实践是什么?
我正在开始一个新项目并且必须选择一个ORM.开发过程需要经常发布中间测试版本,并且每个版本可能会在数据库结构中发生更改.每个新版本都必须轻轻升级数据库以保持当前数据.
对于旧的解决方案,我将提供一组SQL脚本,用于将数据库从v1升级到v2,从v2升级到v3等,并按顺序执行它们.
但它如何为ORM工作?我还应该编写SQL脚本来升级数据库吗?
我知道简单地添加新字段不会导致问题(例如,请参阅XPO的UpdateSchema()方法),但是如果我必须拆分表并将当前记录重新分配到2个新表中呢?
我无法对其他ORM发表评论,但自2007年以来,我一直使用DevExpress XPO作为企业资金管理应用程序.每个版本的架构都有一些变化,但多年来也有一些重大的架构变化.默认XPO升级机制的某种扩展版本可以轻松满足所有更改.
有良好的基本信息,这里有关升级XPO应用.
DevExpress提供DBUpdater工具来帮助您完成升级生产环境的任务.您可以扩展此工具以满足其他要求.在我的应用程序中,我们添加了一些日志记录选项,使用回滚预览等.
每个模块都有虚拟UpdateDatabaseBeforeSchemaUpdate()和UpdateDatabaseAfterSchemaUpdate()方法.您可以在这些内部显着控制升级过程.
正如您所提到的,某些升级将由XPO自动处理(例如,添加新列),但有些事情需要额外的控制,例如使用现有记录的默认值初始化新列.
例如,假设MyNewField已经添加到MyEntity应用程序2.0版的XPO类中.假设现有记录的默认值应为3.XPO将处理新列的创建,但现有记录将为NULL.(如果在XPO类中指定默认值,则它仅适用于新记录).为了纠正现有记录的值,您可以在实体模块中重写以下内容UpdateDatabaseAfterSchemaUpdate():
public override void UpdateDatabaseAfterUpdateSchema()
{
base.UpdateDatabaseAfterUpdateSchema();
if (CurrentDBVersion < new Version(2, 0, 0, 0))
ObjectSpace.GetSession().ExecuteNonQuery(
"UPDATE [MyEntity] SET [MyNewField] = 3 WHERE [MyNewField] IS NULL");
}
Run Code Online (Sandbox Code Playgroud)
(如果您更喜欢避免使用直接SQL,也可以使用ObjectSpace.GetObjects<MyEntity>()和foreach.)
在将表分成两个的更极端的示例中,您可以使用相同的方法,但是您将覆盖UpdateDatabaseBeforeUpdateSchema(),运行SQL以拆分表,让XPO执行任何其他架构更新,并在必要时填充任何默认值这个UpdateDatabaseAfterUpdateSchema().
你会发现,你碰到问题的约束如外键冲突,所以你可能会发现你需要写一些一般的程序,如DropAllForeignKeyConstraints()为部分UpdateDatabaseBeforeUpdateSchema().有时您会发现XPO已经提供了某些东西,有时却没有.缺少约束和索引将在架构更新中重新生成.(根据我的经验,切换主数据表的主键是最难的更新例程.)
默认情况下,调用都发生在SQL事务中,因此如果有任何失败,它应该全部回滚.
开发人员需要了解域模型的更改何时可能导致底层架构出现问题.
为了进行测试,我们保留了一些旧的客户数据库,并在构建过程中运行一系列前后测试,以确保现有客户能够正确升级他们正在升级的任何版本.在生产中,每当我们遇到问题升级时,问题数据都会添加到此测试库中,以防止将来出现类似问题.
我们正在与主要的国际公司和银行打交道.客户对结果非常满意.在公司的DBA需要签署更改的情况下,他们似乎不介意使用命令行工具来执行升级而不是脚本.
| 归档时间: |
|
| 查看次数: |
12682 次 |
| 最近记录: |