为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

C#
德玛西亚99 2021-08-22 15:36:14
我们需要连接到两个 Oracle 数据库和一个 DB2 数据库。我们将 NHibernate 5 与 Oracle Managed Data Access for Oracle 一起使用。虽然有一些可用的资源,但其中大部分已经很旧了。我们处理过单个数据库没有任何问题,但从未处理过多个数据库。我仍然不知道如何开始。如果有人可以分享一些见解或一些示例代码,将不胜感激。
查看完整描述

1 回答

?
萧十郎

TA贡献1815条经验 获得超13个赞

为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;

    }

}


查看完整回答
反对 回复 2021-08-22
  • 1 回答
  • 0 关注
  • 299 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信