我们的情况是,我们有多个具有相同架构的数据库,但每个数据库都有不同的数据。我们正在创建一个会话工厂来处理这个问题。
问题是我们不知道在运行时我们将连接哪个数据库,何时可以提供。但是在启动时要获得工厂构建,我们需要连接到具有该模式的数据库。我们目前通过在已知位置创建架构并使用它来完成此操作,但我们希望删除该要求。
在未指定连接的情况下,我无法找到创建会话工厂的方法。我们不希望能够在没有参数的情况下使用OpenSession方法,这没关系。
有什么想法吗? 谢谢 安迪
答案 0 :(得分:2)
要么实现自己的IConnectionProvider
,要么将自己的连接传递给ISessionFactory.OpenSession(IDbConnection)
(但请阅读方法关于连接跟踪的评论)
答案 1 :(得分:0)
我们提出的解决方案是创建一个为我们管理这个的类。该类可以使用方法调用中的一些信息来做一些路由逻辑来确定数据库的位置,然后调用OpenSession传递连接字符串。
答案 2 :(得分:0)
你也可以使用brady gaster的优秀NuGet包装。我用自己的NHQS软件包制作了自己的实现,效果非常好。
你可以在这里找到它:
祝你好运!答案 3 :(得分:0)
遇到这个并认为Id为未来的读者添加了我的解决方案,这基本上是Mauricio Scheffer所建议的,它封装了CS的“切换”并提供单点管理(我比这更好地进入每个会话调用,少了'错过'并出错。)
我在客户端身份验证期间获取connecitonstring并在上下文中设置,然后使用以下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