我正在编写一个应用程序,用户可以在其中创建一个或多个存储在数据库中的“目录”。但是,我想允许多种数据库格式(SQL Server和SQL Lite),并且我希望用户能够同时在应用程序中打开多个目录。直到运行时才能知道目录数据库的位置。因此,我不希望在应用程序的配置中存储任何特定的数据库设置。
我刚刚开始使用NHibernate,但我计划为与Catalog相关的所有类创建NHibernate映射。我正试图找出最好的设计模式,以允许我同时使用这组映射与多个数据库。
我想我可以省略项目中指向特定数据库和提供程序的hibernate.cfg.xml
文件,而只是将映射(.hbm.xml)文件构建到程序集中。这是对的吗?
然后当我的应用程序运行时,我从程序集创建一个NHibernate配置,它只包含映射信息而不包含任何特定的提供者/数据库信息。从该配置我将创建一个ISessionFactory
。
然后,当用户想要打开目录时,我会使用正确的提供程序为他们指定的数据库创建一个ADO.NET IDbConnection
。然后,为了访问数据库,我将该特定连接传递给单个SessionFactory的OpenSession()方法。
ISession session = sessionfactory.OpenSession(IDbConnection conn);
我是否在正确的轨道上?我所描述的是否有效,或者有更好的方法吗?
更新
既然我已经做了一些阅读,我认为这不会奏效。为特定的方言/驱动程序等配置了ISessionFactory。因此,当单个ISessionFactory可以在多个IDBConnections之间切换时,这些连接需要是相同类型的数据库。由于ISessionFactory是不可变的,因此无法在支持一种类型的数据库与另一种类型的数据库之间切换实例。它是否正确?我是否应该为我想支持的每种类型的数据库创建简单的ISessionFactories?
答案 0 :(得分:0)
我就这样做了:
您需要两件事 - 多个会话工厂存储在一个Dictionary中,然后另一个抽象层根据代码访问会话工厂。
根据数据库的不同,每个会话工厂的配置都不同。
您的应用程序代码可能如下所示:
var session = NHibernateSessionManager.OpenSession(factoryCode: "SqlLiteSessionFactory");
我发现这是一个有用的模式,因为通常有共享映射的原因,但具有不同的会话工厂配置:例如您可以为异步日志记录或批处理操作配置不同的工厂;您可以使用不同的数据库登录等。使用此模式,您还可以对同一实体使用不同的映射 - 例如,特定用户可能需要通过视图访问实体。