【问题标题】:O/R mappers that can update the database schema automatically?可以自动更新数据库模式的 O/R 映射器?
【发布时间】:2008-12-16 15:38:00
【问题描述】:

是否有任何 O/R 映射器可以在您更新业务对象时自动创建或修改数据库模式?环顾四周后,似乎大多数库都是通过从数据库模式创建业务对象以另一种方式工作的。

我希望拥有该功能的原因是我正在计划一种将其数据存储在客户机器上的数据库中的产品。所以当新版本出来时,我可能不得不更新数据库架构。

另一个要求是映射器支持基于文件的数据库,如 SQLite 或 JET,而不仅仅是 SQL 服务器。

我知道 Developer Express 的 XPO 具有该功能,但我想知道是否有任何替代方案。

谢谢

【问题讨论】:

    标签: .net orm


    【解决方案1】:

    NHibernate 可以为您从业务对象生成数据库架构。

    【讨论】:

      【解决方案2】:

      SubSonic 满足您的需求。它有一个迁移类,可与声波指挥官一起使用。我修改了代码并将其放在我的应用程序的启动中,并让它检查版本差异并自动升级。 这是您需要设置的方式:

      1. 您需要添加版本化迁移类。如果您以前从未使用过 SubSonic,您可能想看看这个 tutorial。以下类保存为 \Migrations\001_initial.cs,如果您从 subsonic 调用 migrate.exe(在 VS 中),它会将当前数据库更新为可用的最新版本。您需要保留 3 位版本前缀作为您的文件名,以便 migrate.exe 如教程中所述正常工作。至于类名,我自己写的迁移类需要下划线和3位版本前缀才能正确检测版本。

      //*不知道为什么我需要这一行来使代码块在下面工作

      namespace MyApps.Migrations
      {
          public class _001_Initial : Migration
          {
              public override void Up()
              {
                  //Execute your upgrade query here
              }
              public override void Down()
              {
                  //Execute your downgrade query here
              }
          }
      }
      
      1. 在应用程序启动期间调用了 CheckForMigration()。 IsUpdateAvailable 将指示您需要更新数据库。您只需要调用 Migrate()。 IsAppVersionOlder 表明您的应用程序是使用旧版本的数据库架构制作的(可能新应用程序的另一个副本已经更新了数据库)。使用此功能,您可以防止旧应用运行并损坏更新后的数据库。

      //

      using System;
      using System.Collections.Generic;
      using SubSonic;
      using SubSonic.Migrations;
      
      namespace MyApps.Migrations
      {
          internal static class MigrationHelper
          {
              const string NameSpace = "MyApps.Migrations";
              private const string SCHEMA_INFO = "SubSonicSchemaInfo";
              public static int CurrentVersion { get { return currentVersion; } }
              public static int AppVersion { get { return latestVersion; } }
              public static bool IsUpdateAvailable { get { return (updateVersion.Count > 0); } }
              public static bool IsAppVersionOlder { get; private set; }
              public static bool Checked { get; internal set; }
              private static int currentVersion;
              private static int latestVersion;
              private static List<string> updateVersion;
              private static List<string> availableVersion;
      
              static MigrationHelper()
              {
                  Checked = false;
              }
      
              /// <summary>
              /// Migrates the specified migration directory.
              /// </summary>
              public static void CheckForMigration()
              {
                  currentVersion = Migrator.GetCurrentVersion("YourProviderName");
                  Type[] allTypes =
                              System.Reflection.Assembly.GetExecutingAssembly().GetTypes();
                  availableVersion = new List<string>();
                  foreach (Type type in allTypes)
                  {
                      if (type.Namespace == NameSpace)
                          if (type.Name.Substring(0, 1) == "_")
                              availableVersion.Add(type.Name);
                  }
      
                  availableVersion.Sort();
                  updateVersion = new List<string>();
                  foreach (string s in availableVersion)
                  {
                      int version = 0;
                      if (int.TryParse(s.Substring(1,3), out version))
                      {
                          if (version > currentVersion)
                          {
                              updateVersion.Add(s);
                          }
                          latestVersion = version;
                      }
                  }
                  IsAppVersionOlder = (latestVersion < currentVersion);
                  //log.WriteLine(string.Format(
                  ///"CheckForMigration: DbVer = {0}, AppVer = {1}, UpdateAvailable = {2}, IsAppOlder = {3}",
                      //currentVersion, latestVersion, updateVersion.Count, IsAppVersionOlder));
                  Checked = true;
              }
      
              internal static void Migrate()
              {
                  foreach (string s in updateVersion)
                  {
                      Migration _migration = (Migration)Activator.CreateInstance(
                          System.Reflection.Assembly.GetExecutingAssembly().GetType(
                          "MyApps.Migrations." + s));
                      _migration.Migrate("YourProviderName", Migration.MigrationDirection.Up);
                      IncrementVersion();
                  }
              }
      
              private static void IncrementVersion()
              {
                  new Update(SCHEMA_INFO, 
                  "YourProviderName").SetExpression("version").EqualTo("version+1").Execute();
              }
      
          }
      }
      

      SubSonic 会自动将名为 SubSonicSchemaInfo 的表添加到您的数据库中,以帮助跟踪数据库版本。

      这篇文章很长,希望我没有错过任何内容

      【讨论】:

        【解决方案3】:

        NHibernate 可以更新架构还是删除并重新创建它?

        【讨论】:

          猜你喜欢
          • 2012-12-12
          • 2010-09-24
          • 1970-01-01
          • 2010-09-17
          • 2023-03-19
          • 1970-01-01
          • 1970-01-01
          • 2010-10-12
          • 2021-11-25
          相关资源
          最近更新 更多