我们有一种情况,我们有多个具有相同架构的数据库,但每个数据库中的数据不同。我们正在创建一个单一的会话工厂来处理这个问题。
问题是我们不知道我们将连接到哪个数据库,直到运行时才能提供它。但是在启动以获取工厂构建时,我们需要使用该模式连接到数据库。我们目前通过在已知位置创建架构并使用它来做到这一点,但我们想删除该要求。
在不指定连接的情况下,我无法找到创建会话工厂的方法。我们不希望能够使用没有参数的 OpenSession 方法,这没关系。
有任何想法吗?谢谢安迪
我们有一种情况,我们有多个具有相同架构的数据库,但每个数据库中的数据不同。我们正在创建一个单一的会话工厂来处理这个问题。
问题是我们不知道我们将连接到哪个数据库,直到运行时才能提供它。但是在启动以获取工厂构建时,我们需要使用该模式连接到数据库。我们目前通过在已知位置创建架构并使用它来做到这一点,但我们想删除该要求。
在不指定连接的情况下,我无法找到创建会话工厂的方法。我们不希望能够使用没有参数的 OpenSession 方法,这没关系。
有任何想法吗?谢谢安迪
实现您自己的IConnectionProvider
或将您自己的连接传递给ISessionFactory.OpenSession(IDbConnection)
(但请阅读该方法关于连接跟踪的评论)
我们提出的解决方案是创建一个为我们管理这个的类。该类可以使用方法调用中的一些信息来做一些路由逻辑来确定数据库在哪里,然后调用 OpenSession 传递连接字符串。
您也可以为此使用来自 brady gaster 的出色 NuGet 包。我用他的 NHQS 包做了我自己的实现,效果很好。
你可以在这里找到它:
http://www.bradygaster.com/Tags/nhqs
祝你好运!
遇到这个并认为我为未来的读者添加了我的解决方案,这基本上是 Mauricio Scheffer 所建议的,它封装了 CS 的“切换”并提供单点管理(我更喜欢这个而不是必须传递到每个会话调用中,而不是'错过'并出错)。
我在客户端身份验证期间获取连接字符串,然后在上下文中设置,然后使用以下 IConnectinProvider 实现,在打开会话时为 CS 设置该值:
/// <summary>
/// Provides ability to switch connection strings of an NHibernate Session Factory (use same factory for multiple, dynamically specified, database connections)
/// </summary>
public class DynamicDriverConnectionProvider : DriverConnectionProvider, IConnectionProvider
{
protected override string ConnectionString
{
get
{
var cxnObj = IsWebContext ?
HttpContext.Current.Items["RequestConnectionString"]:
System.Runtime.Remoting.Messaging.CallContext.GetData("RequestConnectionString");
if (cxnObj != null)
return cxnObj.ToString();
//catch on app startup when there is not request connection string yet set
return base.ConnectionString;
}
}
private static bool IsWebContext
{
get { return (HttpContext.Current != null); }
}
}
然后在 NHConfig 期间将其连接:
var configuration = Fluently.Configure()
.Database(MsSqlConfiguration.MsSql2005
.Provider<DynamicDriverConnectionProvider>() //Like so