可以自动更新数据库模式的 O/R 映射器?

Posted

技术标签:

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

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

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

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

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

谢谢

【问题讨论】:

【参考方案1】:

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

【讨论】:

【参考方案2】:

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

    您需要添加版本化迁移类。如果您以前从未使用过 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
        
    

    在应用程序启动期间调用了 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 可以更新架构还是删除并重新创建它?

【讨论】:

以上是关于可以自动更新数据库模式的 O/R 映射器?的主要内容,如果未能解决你的问题,请参考以下文章

需要的建议:O/R 映射器 [重复]

mybatis之映射器(select)

具有多个后端/DI 时的 ORM 和 POCO - 架构?自动映射器?

带有数据映射器 ORM 的 CodeIgniter

简单映射器模式 C# 代码生成模板

如果映射器在中途失败并且 Hadoop 重试该映射器,自定义计数器会发生啥