我无法评论其他 ORM,但自 2007 年以来,我一直将 DevExpress XPO 用于企业财务应用程序。架构随着每个版本的发布而略有变化,但多年来也发生了一些重大的架构变化。默认 XPO 升级机制的某种扩展版本已轻松满足所有更改。
这里有关于升级 XPO 应用程序的很好的基本信息。
正如您所提到的,某些升级将由 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");
}
(如果您不想直接使用 SQL,也可以使用ObjectSpace.GetObjects<MyEntity>()
and a 。)foreach
在将表一分为二的更极端示例中,您可以使用相同的方法,但您可以改写UpdateDatabaseBeforeUpdateSchema()
,运行 SQL 来拆分表,让 XPO 执行任何其他模式更新,并在必要时填充任何默认值UpdateDatabaseAfterUpdateSchema()
. _
您会发现遇到约束问题,例如外键违规,因此您可能会发现需要编写一些通用例程,例如DropAllForeignKeyConstraints()
作为UpdateDatabaseBeforeUpdateSchema()
. 有时您会发现 XPO 已经提供了一些东西,有时却没有。缺少的约束和索引将在模式更新中重新生成。(根据我的经验,切换主数据表的主键是最难正确更新的例程。)
默认情况下,所有调用都发生在 SQL 事务中,因此如果有任何失败,它都应该回滚。
开发人员需要注意对域模型的更改何时可能导致底层模式出现问题。
对于测试,我们保留一些旧的客户数据库,并在构建过程中运行一系列前后测试,以确保现有客户能够正确升级他们正在升级的任何版本。在生产中,每当我们遇到升级问题时,都会将问题数据添加到此测试库中,以防止将来出现类似问题。
我们正在与主要的国际公司和银行打交道。客户对结果非常满意。在公司的 DBA 需要签署更改的情况下,他们似乎不介意使用命令行工具而不是脚本来进行升级。