如何使用NHibernate连接到单个应用程序中的多个数据库?

我们需要连接两个Oracle数据库和一个DB2数据库。 我们正在使用NHibernate 5和Oracle托管数据访问Oracle。 虽然有一些资源可用,但大多数都很老。

我们与个人数据库合作没有任何问题,但从不使用多个数据库。 我仍然不知道如何开始。 如果有人可以分享一些见解或一些示例代码,真的很感激。

为每个数据库创建和维护单独的ISessionFactory实例是ISessionFactory的方法。 所以在你的情况下,你将有三个实例。 我已经在我的一个应用程序中实现了这一点,我连接到三个不同的RDBMS的三个数据库。

正如你所说,你已经使用过单一数据库和NHibernate,我认为不需要任何特定的代码。 同样,只有多个会话工厂实例。 无论如何,我在答案结束时复制了我的代码。

在创建ISession实例时,请确保从要连接的会话工厂实例创建它。 您的其余应用程序保持不变。

请注意,它可能会像我面对的那样记录时产生问题。 但是,那只是一个。 其他一切都没有问题。

示例代码:

注意:下面代码中的某些类型不是NHibernate类型。 那些是他们的包装。 名字相似; 所以理解代码应该没有问题。

 public sealed class NHSessionFactory { /* * This must be instance class. * New instance should be created for each Database Schema. * Maintain the instance in calling application. * This is useful if multiple databases are used in one application. */ NHSessionFactoryInternal nhSessionFactoryInternal = null; public void Start(NHSessionFactoryStartParams startParams) { Configuration nhConfiguration; nhConfiguration = new Configuration(); nhConfiguration.SetProperty(NHibernate.Cfg.Environment.Dialect, startParams.Dialect); nhConfiguration.SetProperty(NHibernate.Cfg.Environment.ConnectionString, startParams.ConnectionString); if(string.IsNullOrEmpty(startParams.DefaultSchema) == false) nhConfiguration.SetProperty(NHibernate.Cfg.Environment.DefaultSchema, startParams.DefaultSchema); nhConfiguration.SetProperty(NHibernate.Cfg.Environment.Isolation, "ReadCommitted"); nhConfiguration.SetProperty(NHibernate.Cfg.Environment.BatchSize, NHSettings.DefaultBatchSize.ToString()); if(string.IsNullOrEmpty(startParams.LogFilePath) == false) { nhConfiguration.SetProperty(NHibernate.Cfg.Environment.ShowSql, "true"); nhConfiguration.SetProperty(NHibernate.Cfg.Environment.FormatSql, "true"); } else { nhConfiguration.SetProperty(NHibernate.Cfg.Environment.ShowSql, "false"); nhConfiguration.SetProperty(NHibernate.Cfg.Environment.FormatSql, "false"); } nhConfiguration.AddMapping(startParams.HbmMappingInstance); try { nhSessionFactoryInternal = new NHSessionFactoryInternal(); nhSessionFactoryInternal.CreateSessionFactory(nhConfiguration); } catch(Exception exception) { Stop(); throw new NHWrapperException("Failed to create session factory.", exception); } } public void Stop() { if(nhSessionFactoryInternal == null) return; nhSessionFactoryInternal.CloseSessionFactory(); nhSessionFactoryInternal = null; } public INHSession CreateSession(bool readOnly) { if(nhSessionFactoryInternal == null) throw new NHWrapperException("NHWrapper is not started."); return nhSessionFactoryInternal.CreateNHSession(readOnly); } } 

以下是在上面的代码中使用的NHSessionFactoryInternal类的实现。 您可以毫无问题地组合这两个类。 我还有其他一些部分; 所以我更喜欢把它分开。

 internal sealed class NHSessionFactoryInternal { ISessionFactory sessionFactory; internal ISessionFactory SessionFactory { get { return sessionFactory; } } internal void CreateSessionFactory(Configuration nhConfiguration) { if(sessionFactory != null) throw new NHWrapperException("SessionFactory is already created."); try { sessionFactory = nhConfiguration.BuildSessionFactory(); } catch(Exception exception) { throw new NHWrapperException("Failed to build session factory.", exception); } } internal INHSession CreateNHSession(bool readOnly = false) { if(sessionFactory == null) throw new NHWrapperException("Session factory is not build."); return new NHSession(sessionFactory.OpenSession(), NHSettings.DefaultFlushMode, readOnly); } internal void CloseSessionFactory() { if(sessionFactory == null) return; if(sessionFactory.IsClosed == false) sessionFactory.Close(); sessionFactory.Dispose(); sessionFactory = null; } }