【问题标题】:NHibernate and database changes/deploymentNHibernate 和数据库更改/部署
【发布时间】:2010-01-09 00:20:13
【问题描述】:

我正在考虑在我的下一个项目中使用 NHibernate 和 Fluent NHibernate,但我想事先澄清一件事是如何管理对数据库的更改?

例如,我有 NH + FNH 工作,应用程序已部署并运行,但我们在开发环境中进行了更改,例如,我们向使用 NH/FNH 映射的实体添加新属性。

如何在不删除表的情况下将更改应用到数据库?

谢谢 通用电气

【问题讨论】:

    标签: sql nhibernate deployment fluent-nhibernate


    【解决方案1】:

    我有很好的使用这个框架的经验:

    http://code.google.com/p/migratordotnet/

    基本上,您为每个数据库更改创建一个类,并用时间戳注释该类。然后按时间戳顺序应用最终程序集。

    这意味着在开发过程中,每次结帐后,盲目地运行数据库升级过程变得很容易,并且知道您与世界同步。

    using Migrator.Framework;
    using System.Data;
    
    namespace DBMigration
    {
        [Migration(20080401110402)]
        public class CreateUserTable_001 : Migration
        {
                public void Up()
                {
                        Database.CreateTable("User",
                                new Column("UserId", DbType.Int32,
                                ColumnProperties.PrimaryKeyWithIdentity),
                                new Column("Username", DbType.AnsiString, 25)
                                );
                }
    
                public void Down()
                {
                        Database.RemoveTable("User");
                }
        }
    

    【讨论】:

    • 不错。这基本上是 Rails 方法的一个端口。
    【解决方案2】:

    AFAIK ,您需要手动完成。您可以在每次初始化时导出架构,但不能自动更改表。因为架构将只包含创建语句。

    也许,您可以使用 Red Gate 之类的工具来查找您的数据库差异,并可以自动为您创建语句。这个想法是,

    -在测试数据库上生成模式
    - 运行 Red Gate 工具,找到模式级别的 DIFF。
    - 自动创建差异脚本
    - 在你的主数据库上应用差异

    【讨论】:

      【解决方案3】:

      NHibernate 支持 SchemaUpdate 类,它可以进行 一些 模式修改,但不是全部。这里有更多细节:

      How to update database table schemas with NHibernate schema generation?

      【讨论】:

        【解决方案4】:

        无论您使用什么 ORM 工具,如果您进行架构更改,您将不得不同时部署代码和架构更改。对于我们的项目,这意味着对于每个包含架构更改的版本,我们都会编写一个用于更新数据库的 sql 脚本。该脚本由我们的安装程序在将包含新休眠映射的代码部署到服务器的同时运行,并且在模式修改完成之前不会启动新应用程序。

        使用该技术,我们能够更改表、删除表、添加表以及将数据从一个表迁移到另一个表,而不会出现任何重大问题。拥有执行数据库修改的脚本可以让您在部署到生产环境之前对其进行彻底测试。

        【讨论】:

        • 我意识到它在许多商店都是现实世界,这种做法可能会变得非常失控,尤其是在需要高正常运行时间的关键任务应用程序中。将代码更改部署到一组服务器(例如 20 多个)并同时更改数据库可能对正常运行时间非常不利,如果需要回滚,可能会导致长时间停机。
        • 所有优点。当我们进行发布时,我们确实会遇到一些停机时间,并且会在下班后完成。我们有 2 个 Web 服务器和 1 个数据库服务器。我很想看看您对您提到的问题的解决方案。
        【解决方案5】:

        这是我制定的过程。我认为它相当光滑。

        这个过程是这样的,假设你有一个名为 'MyDb' 的数据库

        1. 在模型和 NH 映射中进行更改
        2. 运行脚本以删除然后重新创建名为 MyDb_Next 的数据库,并执行 NH SchemaExport 以将新架构写入其中
        3. 使用我的工具MigrationScriptGenerator 比较MyDb 和MyDb_next。这将通过比较架构和创建语句以添加新列等来生成您的更改脚本(或尽可能多的脚本)。脚本将保存到 VS 项目中的 xxxx - updatescript.sql.suggested 文件中
        4. 如有必要,修复建议的 sql 脚本(当它检测到可能丢失数据的更改时需要人工输入),并重命名为 .sql(以便在下一步中提取)
        5. 包含 sql 脚本的项目的构建后事件运行我的工具 simplescriptrunner 这会将 sql 脚本应用到 MyDb,使其保持最新

        您只需在更改实体时重复此过程。我通常将我的 SQL 脚本存储在 .csproj 中,并有一个运行 simplescriptrunner 的构建后事件。这样,任何其他进行更新和重建的开发人员都将在他们的机器上通过签入的编号脚本生成最新版本的数据库。

        MigrationScriptGenerator 使用 OpenDBDiff(一种类似于 Red Gate SQL Compare 的开源工具)来进行脚本生成。如果您想自己创建脚本,您可能会发现这很有用。

        PS 这些工具仅适用于 SQL Server - 抱歉!

        【讨论】:

          【解决方案6】:

          我知道这是一个老问题,但我发现它是 google 的最高结果,它没有提到似乎是 NHibernate 迁移标准的工具 - Fluent Migrator

          【讨论】:

          • 第二。 FluentMigrator 已经超越了 migratordotnet,并提供了一种更易于管理(阅读:更少的手动脚本)的版本控制方式。
          猜你喜欢
          • 1970-01-01
          • 2013-07-27
          • 1970-01-01
          • 1970-01-01
          • 2023-03-31
          • 2017-02-12
          • 2023-04-09
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多