如何使用nhibernate / lightcore注册两个数据库连接?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何使用nhibernate / lightcore注册两个数据库连接?相关的知识,希望对你有一定的参考价值。

我必须使用Fluent Nhibernate为我的C#Mvc Applicaton设置现有数据库(Ms Sql)另一个(PostgreSql)。有人知道如何在LightCoreConfiguration(global.asax)中注册postgreSql数据库?

Global.asax中

protected void Application_Start()
{
    MvcHandler.DisableMvcResponseHeader = true;

    AreaRegistration.RegisterAllAreas();

    RegisterRoutes(RouteTable.Routes);

    RegisterDependencies();

    RegisterValidators();

}
private static void RegisterDependencies()
{
    var builder = new ContainerBuilder();
    builder.DefaultControlledBy<HttpRequestLifecycle>();

// This is the current Ms Sql connection to the database that works and I have register here another connection to the postgreSql database
    builder.Register(c => NHConfiguration.CreateSessionFactory()).ControlledBy<SingletonLifecycle>();
    builder.Register(c => c.Resolve<ISessionFactory>().OpenSession()).ControlledBy<HttpRequestLifecycle>();

    LightCoreConfiguration.RegisterGlobalDependencies(builder);
    _container = builder.Build();

}

NHConfiguration.cs

public static class NHConfiguration
    {

        private static FluentConfiguration CreateConfiguration()
        {
            return Fluently.Configure()
                           .Database(MsSqlConfiguration.MsSql2008
                                                       .ConnectionString(SessionFacade.DatabaseConnectionString)
                                                       .ShowSql())
                           .Mappings(m => m.FluentMappings
                                           .AddFromAssemblyOf<Entity>()
                                           .AddFromAssemblyOf<CustomEntity>()
                                           .Conventions.AddFromAssemblyOf<EnumConvention>())
                           .Cache(c => c.ProviderClass<SysCacheProvider>()
                                        .UseQueryCache()
                                        .UseSecondLevelCache());
        }

        private static FluentConfiguration CreatePostgresConfiguration()
        {
            return Fluently.Configure()
                           .Database(PostgreSQLConfiguration.Standard.ConnectionString(SessionFacade.DatabasePostgresConnectionString).ShowSql())
                           .Mappings(m => m.FluentMappings
                                           .AddFromAssemblyOf<Entity>()
                                           .AddFromAssemblyOf<CustomEntity>()
                                           .Conventions.AddFromAssemblyOf<EnumConvention>()
                                           .Conventions.Add(new IdentityConvention()))
                           .Cache(c => c.ProviderClass<SysCacheProvider>()
                                        .UseQueryCache()
                                        .UseSecondLevelCache());
        }

        public static ISessionFactory CreateSessionFactory()
        {
            return CreateConfiguration().BuildSessionFactory();
        }

        public static ISessionFactory CreatePostgresSessionFactory()
        {
            return CreatePostgresConfiguration().BuildSessionFactory();
        }
    }

我已经尝试在没有lightcore的情况下设置数据库连接(并在应用程序完成请求后关闭会话),但是然后抛出了连接已经关闭的错误,所以我想我必须用lightcore注册会话。

答案

我现在找到了解决方案,以便可以使用两个数据库,您可以在哪里决定每个实体本身,应该使用哪个数据库:

Global.asax中

private static void RegisterDependencies()
{
    var builder = new ContainerBuilder();

    builder.DefaultControlledBy<HttpRequestLifecycle>();

    SessionFacade.DatabaseSessionFactories[DbConnectionSessionType.MsqlSession] = NHConfiguration.CreateSessionFactory();
    SessionFacade.DatabaseSessionFactories[DbConnectionSessionType.PostgresqlSession] = NHConfiguration.CreatePostgresSessionFactory();

    builder.Register(c => c.ResolveAll<IDatabaseSessions>()).ControlledBy<HttpRequestLifecycle>();

    LightCoreConfiguration.RegisterGlobalDependencies(builder);

    // Build the container.
    _container = builder.Build();
}
protected void Application_EndRequest(object sender, EventArgs e)
{
            var sessions = _container.Resolve<IDatabaseSessions>();

            sessions.MssqlSession.Close();
            sessions.MssqlSession.Dispose();

            sessions.PostgresqlSession.Close();
            sessions.PostgresqlSession.Dispose();
}

SessionFacade.cs

public static class SessionFacade
{
    /// <summary>
    /// Gets the database connection string.
    /// </summary>
    public static string DatabaseConnectionString => Environment.GetEnvironmentVariable("Database:Connection");

    public static string DatabasePostgresConnectionString => Environment.GetEnvironmentVariable("DatabasePostgres:Connection");

    public static Dictionary<DbConnectionSessionType, ISessionFactory> DatabaseSessionFactories
    {
        set; get;
    } = new Dictionary<DbConnectionSessionType, ISessionFactory>() {
        {
            DbConnectionSessionType.MsqlSession,
            null
        },
        {
            DbConnectionSessionType.PostgresqlSession,
            null
        }
    };
}

IDatabaseSessions

public interface IDatabaseSessions
{
    ISession MssqlSession { get; set; }
    ISession PostgresqlSession { get; set; }
}

LightCoreConfiguration

public static class LightCoreConfiguration
    {

        public static void RegisterGlobalDependencies(ContainerBuilder builder)
        {
builder.Register<IDatabaseSessions, DatabaseSessions>();
        }
    }
}

DatabaseSessions

public class DatabaseSessions: IDatabaseSessions
{
    public DatabaseSessions()
    {
        MssqlSession = SessionFacade.DatabaseSessionFactories[DbConnectionSessionType.MsqlSession].OpenSession();
        PostgresqlSession = SessionFacade.DatabaseSessionFactories[DbConnectionSessionType.PostgresqlSession].OpenSession();
    }

    public ISession MssqlSession { get; set; }
    public ISession PostgresqlSession { get; set; }
}

Repository.cs

public class Repository<T> : IRepository<T> where T : Entity
{
    public Repository(IDatabaseSessions databaseSessions, DbConnectionSessionType connectionType = DbConnectionSessionType.PostgresqlSession)
            {
                if(connectionType == DbConnectionSessionType.MsqlSession) _session = databaseSessions.MssqlSession;
                if(connectionType == DbConnectionSessionType.PostgresqlSession) _session = databaseSessions.PostgresqlSession;
            }
    }
}

最后的服务

public class UserService
    {
        public UserService(IDatabaseSessions databaseSessions) : base(new Repository<User>(databaseSessions))
        {
        }
}

以上是关于如何使用nhibernate / lightcore注册两个数据库连接?的主要内容,如果未能解决你的问题,请参考以下文章

NHIbernate:如何使用 ICompositeUserType 映射包

如何使用 NHibernate 模式生成更新数据库表模式?

如何使用 NHibernate 迭代整个表?

NHibernate - 如何使用 where 子句保存对象

如何使用 MySQL 配置流畅的 nHibernate

Nhibernate - 如何使用 CompositeId 设计域对象和映射