nHibernate、ASP.NET MVC、s#arp 架构和多个相同的数据库
我们目前正在开发一个基于 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;
}
}
此连接提供程序检查上下文对象中的客户代码并相应地设置连接字符串。
我们计划提供一个 HttpContext 感知的 ITTTContextProvider
。为此,我有两个问题:
我们如何从 url 中检索客户代码并将其放入每个请求的上下文对象中?当我们使用以下路线时?
/{customercode}/{controller}/{action}/{id} 这种连接到多个相同数据库的方法是否有效,或者更好的做法是为每个客户数据库构建一个会话工厂?
We are currently developing an application based on NHibernate and ASP.NET MVC and a SQL Server backend. Since I'm fairly new to NHibernate, I'm tryig to understand best practices.
Our application requires every user to have it's own SQL Server database. These databases all have an identical structure.
Our customers are identified with a customercode, e.g. 1500.
We've come up with a custom connection provider for nHibernate, which we already use in our nServiceBus backend services:
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;
}
}
This connection provider checks the customer code in a context object and sets the connectionstring accordingly.
We are planning to provide a HttpContext aware ITTTContextProvider
. For this I have two questions:
How can we retrieve the customer code from the url and put it into our context object for every request? when we use the following route?
<main-site-url>/{customercode}/{controller}/{action}/{id}
Is this method of connecting to several identical databases valid or is it better practice to construct a sessionfactory foreach customer database?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
为了获取您需要访问路线数据的
customercode
,我的第二个建议的内容是不要将此代码放在上面提供的代码片段中。把它抽象出来。请参阅 Joshua 的回答强调了我正在考虑的方法。
对第二个问题确实没有帮助,实际上对提到的两个框架都不熟悉。
In order to get the
customercode
you need to access the route data, something along the lines ofMy second suggestion would be not to put this code in the above snippet provided. Abstract it away. See Joshua's answer which highlights the approach I am thinking of.
Can't really help on the second question, actually not familiar with both frameworks mentioned.
请参阅我最近的博客文章,其中展示了如何使用子域连接到不同的数据库,尽管实现您自己的 ITenantContext 版本(从请求 URL 中获取客户代码)很容易。还为每个租户使用单独的会话工厂。
http://www.yellowfeather.co.uk/ 2011/01/夏普架构上的多租户/
See my recent blog post which shows how to use a subdomain to connect to different databases, although it would be easy to implement your own version of ITenantContext that grabbed the customer code from the request url. Also uses separate session factories for each tenant.
http://www.yellowfeather.co.uk/2011/01/multi-tenancy-on-sharp-architecture/