Entity framework DevExpress XPO vs NHibernate vs Entity Framework:数据库升级问题

Entity framework DevExpress XPO vs NHibernate vs Entity Framework:数据库升级问题,entity-framework,nhibernate,devexpress,upgrade,xpo,Entity Framework,Nhibernate,Devexpress,Upgrade,Xpo,使用ORM(、或)升级数据库的最佳实践是什么 我正在启动一个新项目,必须选择一个ORM。开发过程需要经常发布中间测试构建,并且每个构建都可能会在数据库结构中发生更改。每个新版本都必须温和地升级数据库以保持当前数据 对于旧的解决方案,我将提供一组SQL脚本,用于将数据库从v1升级到v2、从v2升级到v3等,并按顺序执行它们 但它将如何为ORM工作呢?我还应该编写SQL脚本来升级数据库吗 我知道简单地添加新字段不会导致问题(例如,请参阅XPO),但如果我必须拆分一个表并将当前记录重新分配到两个新表,

使用ORM(、或)升级数据库的最佳实践是什么

我正在启动一个新项目,必须选择一个ORM。开发过程需要经常发布中间测试构建,并且每个构建都可能会在数据库结构中发生更改。每个新版本都必须温和地升级数据库以保持当前数据

对于旧的解决方案,我将提供一组SQL脚本,用于将数据库从v1升级到v2、从v2升级到v3等,并按顺序执行它们

但它将如何为ORM工作呢?我还应该编写SQL脚本来升级数据库吗


我知道简单地添加新字段不会导致问题(例如,请参阅XPO),但如果我必须拆分一个表并将当前记录重新分配到两个新表,该怎么办?

大多数迁移解决方案可以处理简单的任务,如添加新列、关系或删除一个,但重命名列时无法工作(这是一个add?还是在add之后的remove,它等于重命名?在这种情况下,您应该如何处理数据?)

这三种解决方案都有基本的迁移支持,XPO甚至允许您在迁移过程中运行自己的脚本(插入静态/测试/连续数据等)

还有一个项目,您可以使用它,而不必依赖于任何特定于ORM的迁移特性

就我个人而言,我只会在开发/测试环境中使用自动迁移,并且在特定于客户端的数据库上运行时会有一整套升级脚本,比如说从v1升级到v2

ORM将如何工作?我还应该为其编写SQL脚本吗 升级数据库

这个问题的明确答案应该是程序员的stackexchange线程-,在这里,我得到了您提出的问题的简单答案,并与我在使用实体框架和代码smith ORM模板开发一些项目时使用ORM的经验相匹配

ORM如何管理数据模型中的更改?如果我必须拆分一个表并将当前记录重新分配到两个新表中怎么办?

有些可以在一定范围内自动更新数据库,有些则可以 什么都不做,你就得自己干脏活;其他的 提供一个框架,用于处理允许您控制数据库的更改 更新。有人需要花一个小时更新模型以添加表或更改正在更改的数据类型

参考:


我无法评论其他ORM,但自2007年以来,我已将DevXPress XPO用于一个公司财务应用程序。每一个版本的架构都会有一些变化,但多年来也有一些大的架构变化。默认XPO升级机制的扩展版本已经很好地满足了所有的需求恩格斯

有关于升级XPO应用程序的良好基本信息

  • DevXPress提供了一个DBUpdater工具来帮助您升级生产环境。您可以扩展此工具以满足其他要求。在我的应用程序中,我们添加了一些日志记录、带回滚的预览等选项

  • 每个模块都有虚拟的
    UpdateDatabaseBeforeSchemaUpdate()
    UpdateDatabaseBeforeSchemaUpdate()
    方法。您可以在这些方法中显著控制升级过程

正如您所提到的,XPO将自动处理一些升级(例如,添加新列),但有些事情需要额外的控制,例如使用现有记录的默认值初始化新列

例如,假设已将
MyNewField
添加到应用程序2.0版中的
MyEntity
XPO类中。假设现有记录的默认值为3。XPO将处理新列的创建,但现有记录将为空。(如果在XPO类中指定默认值,则该值仅适用于新记录)。为了更正现有记录的值,您需要向实体模块的重写
UpdateDatabaseAfterSchemaUpdate()
中添加以下内容:

public override void UpdateDatabaseAfterUpdateSchema()
{
base.UpdateDatabaseAfterUpdateSchema();
if(当前数据库版本<新版本(2,0,0,0))
ObjectSpace.GetSession().ExecuteOnQuery(
“更新[MyEntity]集[MyNewField]=3,其中[MyNewField]为空”);
}
(如果希望避免使用直接SQL,还可以使用
ObjectSpace.GetObjects()
foreach

在将表一分为二的更极端示例中,您可以使用相同的方法,但您可以替代
UpdateDatabaseBeforeUpdateSchema()
,运行SQL拆分表,让XPO执行任何其他架构更新,并在
UpdateDatabaseAfterUpdateSchema()
中填充任何默认值

您会发现遇到约束问题,例如外键冲突,因此您可能需要编写一些常规例程,例如
DropAllForeignKeyConstraints()
,作为
UpdateDatabaseBeforeUpdateSchema()的一部分
。有时您会发现XPO已经提供了一些功能,有时却没有。缺少的约束和索引将在架构更新中重新生成。(根据我的经验,切换主数据表的主键是最难正确执行的更新例程。)

默认情况下,所有调用都发生在SQL事务中,因此,如果任何调用失败,都应该回滚

开发人员需要知道域模型的更改何时可能导致底层模式出现问题

为了进行测试,我们保留了一些旧客户数据库,并在构建过程中运行了一系列前后测试,以确保现有客户能够正确升级他们从中升级的任何版本。在produc中
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");
}