如何使用NHibernate在单个应用程序中连接到多个数据库? [英] How to connect to multiple databases in single application with NHibernate?

查看:129
本文介绍了如何使用NHibernate在单个应用程序中连接到多个数据库?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们需要连接到两个Oracle数据库和一个DB2数据库.我们正在将NHibernate 5与用于Oracle的Oracle Managed Data Access一起使用. 尽管有一些可用资源,但其中大多数都已经很旧了.

We have a requirement of connecting to two Oracle databases and one DB2 database. We are using NHibernate 5 with Oracle Managed Data Access for Oracle. Although there are some resources available, most of them are quite old.

我们使用单个数据库没有问题,但是从来没有使用多个数据库.我仍然不知道如何开始.如果有人可以分享一些见解或示例代码,我将不胜感激.

We have worked with individual databases with no issues, but never with multiple. I still have no idea how to start. Would really appreciate if someone could share some insights or some sample code.

推荐答案

为每个数据库创建和维护单独的ISessionFactory实例是必经之路.因此,在您的情况下,您将有三个实例.我已经在我的一个应用程序中实现了此功能,在该应用程序中,我使用三个不同的RDBMS连接到三个数据库.

Creating and maintaining separate ISessionFactory instance per database is the way to go. So in your case, you will have three instances. I have implemented this in one of my application where I connect to three databases with three different different RDBMS.

正如您所说,您已经使用单个数据库和NHibernate,我认为不需要任何特定的代码.相同,只是多个会话工厂实例.无论如何,我已经在答案的末尾复制了我的代码.

As you said, you have already worked with single database and NHibernate, I do not think any specific code is needed. Its same, just multiple session factory instances. Anyway, I have copied my code at the end of answer.

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

While creating ISession instance, make sure you are creating it from the session factory instance you want to connect to. Your rest of the application remains same.

请注意,它可能会在我遇到的一个记录时创建问题.但是,那只是一个.其他一切都顺利,没有问题.

Note that it may create an issue while logging like the one I faced. But, that was just one. Everything else went fine without issues.

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

Note: Some of the types in code below are NOT NHibernate types. Those are wrappers over them. Names are similar; so there should not be an issue understanding the code.

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类的实现.您可以毫无问题地结合使用这两个类.我在那里还有其他部分.所以我更喜欢把它分开.

and below is the implementation of NHSessionFactoryInternal class which is used in above code. You may combine these two classes without issue. I have some other part in there; so I prefer to put it separate.

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

这篇关于如何使用NHibernate在单个应用程序中连接到多个数据库?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆