Asp.net mvc nHibernate、ASP.NET MVC、s#arp体系结构和多个相同的数据库

Asp.net mvc nHibernate、ASP.NET MVC、s#arp体系结构和多个相同的数据库,asp.net-mvc,nhibernate,s#arp-architecture,multiple-databases,Asp.net Mvc,Nhibernate,S#arp Architecture,Multiple Databases,我们目前正在开发一个基于NHibernate和ASP.NET MVC以及SQL Server后端的应用程序。因为我是NHibernate的新手,所以我试图了解最佳实践 我们的应用程序要求每个用户都有自己的SQL Server数据库。这些数据库都具有相同的结构 我们的客户通过客户代码识别,例如1500 我们为nHibernate提供了一个自定义连接提供程序,我们已经在我们的nServiceBus后端服务中使用了它: public class DynamicConnectionProvider :

我们目前正在开发一个基于NHibernate和ASP.NET MVC以及SQL Server后端的应用程序。因为我是NHibernate的新手,所以我试图了解最佳实践

我们的应用程序要求每个用户都有自己的SQL Server数据库。这些数据库都具有相同的结构

我们的客户通过客户代码识别,例如1500

我们为nHibernate提供了一个自定义连接提供程序,我们已经在我们的nServiceBus后端服务中使用了它:

public class DynamicConnectionProvider : DriverConnectionProvider
{
    public override IDbConnection GetConnection()
    {
        IDbConnection conn = Driver.CreateConnection();

        try
        {
            var messageExecutionContext = ServiceLocator.Current.GetInstance<ITTTContextProvider>().CurrentContext;
            if (messageExecutionContext.CustomerId == 0)
            {
                conn.ConnectionString = ConfigurationManager.ConnectionStrings["dev"]
                    .ConnectionString;
            }
            else
            {
                conn.ConnectionString = ConfigurationManager.ConnectionStrings["default"]
                    .ConnectionString
                    .FormatWith(messageExecutionContext.CustomerId);
            }

            conn.Open();
        }
        catch (Exception)
        {
            conn.Dispose();
            throw;
        }
        return conn;
    }
}
公共类DynamicConnectionProvider:DriverConnectionProvider
{
公共覆盖IDbConnection GetConnection()
{
IDbConnection conn=Driver.CreateConnection();
尝试
{
var messageExecutionContext=ServiceLocator.Current.GetInstance().CurrentContext;
如果(messageExecutionContext.CustomerId==0)
{
conn.ConnectionString=ConfigurationManager.ConnectionString[“dev”]
.连接字符串;
}
其他的
{
conn.ConnectionString=ConfigurationManager.ConnectionString[“默认值”]
.连接字符串
.FormatWith(messageExecutionContext.CustomerId);
}
conn.Open();
}
捕获(例外)
{
conn.Dispose();
投掷;
}
返回连接;
}
}
此连接提供程序检查上下文对象中的客户代码,并相应地设置connectionstring

我们计划提供一个HttpContext-aware
ITTTContextProvider
。为此,我有两个问题:

  • 我们如何从url中检索客户代码,并将其放入每个请求的上下文对象中?我们什么时候走下面的路线

    /{customercode}/{controller}/{action}/{id}

  • 这种连接到多个相同数据库的方法有效吗?还是为每个客户数据库构造sessionfactory更好


  • 为了获得
    customercode
    ,您需要访问路线数据

    HttpContextBase currentContext = new HttpContextWrapper(HttpContext.Current); //ServiceLocator.Current.GetInstance<ITTTContextProvider>().CurrentContext; 
    RouteData routeData = RouteTable.Routes.GetRouteData(currentContext);  
    var cusomterCode = routeData.Values["customercode"]
    
    HttpContextBase currentContext=新的HttpContextWrapper(HttpContext.Current)//ServiceLocator.Current.GetInstance().CurrentContext;
    RouteData RouteData=RouteTable.Routes.GetRouteData(currentContext);
    var cusomterCode=routeData.Values[“customercode”]
    
    我的第二个建议是不要将此代码放在上面提供的代码段中。把它抽出来。看看哪一个突出了我正在考虑的方法


    在第二个问题上,我实在帮不上什么忙,实际上我对上面提到的两个框架都不熟悉。

    请参阅我最近的博客文章,其中展示了如何使用子域连接到不同的数据库,尽管实现您自己版本的ITenantContext很容易,它从请求url获取了客户代码。还为每个租户使用单独的会话工厂


    最初在答案中-据我回忆,创建会话工厂是一项昂贵的操作,这可能会影响您的决策。现在考虑到有多个数据库,也取决于每个数据库的预期点击量,这可能是一个关键因素。会话工厂是否有缓存等在您的情况下可能有用的好处?这可能会有所帮助-缓存是我们将来可能需要的东西。但是,第二级缓存是如何实现的?每会话工厂或每连接(字符串)?@Rik-抱歉,正如我说的,我对这两个框架都不太熟悉,也没有足够的实际操作经验