【问题标题】:Switching Database for the same mapped table为同一个映射表切换数据库
【发布时间】:2012-04-12 13:05:26
【问题描述】:

我使用 Fluent NHibernate,现在必须处理存档数据,其中同一个表存在于多个 MSSQL 数据库中。根据用户提供的日期值,我必须连接到不同的数据库,而所有映射信息保持不变。

更具体:如果提供的 Date 值在当前年份内,则使用 DB CUR,否则使用年度 DB(2011、2010、2009...)。

现在有一段时间人们告诉我一遍又一遍地重新创建一个 SessionFactory 是一件相当昂贵的事情,所以我心想一定有一种方法可以使用现有的 sessionFactory,更新我的 ClassMap (例如将架构从“CUR.DBO”更改为“2011.DBO”)并重新连接。

我尝试将 FluentConfiguration 和 SessionFactory 弄得一团糟,但然后我在膝盖中中了一箭找不到在运行时刷新映射的方法。 p>

我最终会创建一个新的 SessionFactory 吗?或者有没有人知道在运行时重新初始化 (Fluent) NHibernate 映射的可行程序?

编辑: 一个非常重要的细节,SqlConnection 也是外部提供的。它提供对所有数据库的访问,这意味着理论上我永远不必创建连接。所以,基本上我要做的就是为每个 Archive 创建一个 SessionFactory 来更新 Mapping 的 Schema 信息,指向另一个数据库。但这正是我卡住的地方。

【问题讨论】:

  • 为什么不创建 2 个会话工厂?一个用于存档数据库,一个用于生产数据库。
  • 我们每年有一个存档,所以我最终会创建至少 10 个左右。据我所知,这基本上就是我必须要做的,但希望有更聪明的方法......

标签: nhibernate fluent-nhibernate nhibernate-mapping fluent-nhibernate-mapping


【解决方案1】:

确实,创建会话工厂是一项比创建会话更昂贵的操作,因此您当然不想为对数据库的每个查询都创建一个。

但是,根据我的经验,最多只需要几秒钟。

我建议您在每次用户选择不同的年份时创建一个新的。如果您在发生这种情况时给他们很好的反馈(可能是一个对话框,上面写着“连接到 2010 数据库”,带有进度条),他们可能不会介意等待。

一旦你创建了一个一年,如果他们在同一年进行更多查询,你可以重复使用它,这样他们每年只需要等待一次被查询。

如果创建会话工厂花费的时间太长,我已经看到了解释如何保存或缓存配置以减少创建时间的帖子。但是,快速 google 并没有找到任何好的链接,所以你可能需要研究一下,或者问另一个问题。

【讨论】:

    【解决方案2】:

    感谢您的回复/cmets。实际上我还没有找到重用会话工厂的方法,所以我最终按照建议为它们创建了一个查找列表。以下解决方案可以满足我的需要(更改数据库),我们将了解它的执行方式:

        private IDictionary<string, ISessionFactory> _sessionFactories;
    
        public SqlConnection Connection { get; set; }
    
        public ISessionFactory GetSessionFactory(string dbName)
        {
            if (_sessionFactories.ContainsKey(dbName))
            {
                return _sessionFactories[dbName];
            }
    
            FluentConfiguration cfg = Fluently.Configure().Database(MsSqlConfiguration.MsSql2008
                                                                    .ShowSql()
                                                                    .ConnectionString(c=>c.Is(Connection.ConnectionString)))
                                                          .Mappings(x=>x.FluentMappings.Add<MappedClassMap>());
            cfg.ExposeConfiguration(x => x.GetClassMapping(typeof(MappedClass)).Table.Schema = string.Format("{0}.dbo",dbName));
            ISessionFactory sf = cfg.BuildSessionFactory();
            _sessionFactories.Add(dbName, sf);
            return sf;
        }
    

    【讨论】:

      【解决方案3】:

      如果为单个数据库创建会话工厂似乎就足够了。但是,在使用 Sessionfactory 实例打开会话时,可以使用重载方法来提供 dbconnection 对象,我们可以在其中切换数据库。已经验证它并且它工作正常。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-11-21
        • 1970-01-01
        • 2016-07-02
        • 1970-01-01
        • 2010-10-07
        • 1970-01-01
        • 2021-07-23
        • 1970-01-01
        相关资源
        最近更新 更多