我创建了自己的CMS供我自己使用。 目前,我已经使用我的CMS推出了3个网站。并将继续添加。
由于所有网站都使用相同版本的CMS,因此我只需要创建一个管理网站来统治它们。
我使用Subsonic 2.x作为数据访问层。 在管理网站,我必须把所有connectionStrings
<SubSonicService defaultProvider="firstSql">
<providers>
<clear/>
<add name="firstSql" type="SubSonic.SqlDataProvider, SubSonic" connectionStringName="first" generatedNamespace="firstSql"/>
<add name="secondSql" type="SubSonic.SqlDataProvider, SubSonic" connectionStringName="second" generatedNamespace="second"/>
<add name="thirdSql" type="SubSonic.SqlDataProvider, SubSonic" connectionStringName="third" generatedNamespace="thirdSql"/>
</providers>
</SubSonicService>
<connectionStrings>
<clear/>
<add name="first" connectionString="Data Source=123.123.12.3;Initial Catalog=first;User ID=first;Password=first" providerName="System.Data.SqlClient"/>
<add name="second" connectionString="Data Source=123.123.12.3;Initial Catalog=second;User ID=second;Password=second" providerName="System.Data.SqlClient"/>
<add name="third" connectionString="Data Source=123.123.12.3;Initial Catalog=third;User ID=third;Password=third" providerName="System.Data.SqlClient"/>
</connectionStrings>
这是丑陋的代码
switch(sitename){
case "first":
var comment1 = new firstSql.Comment(id);
comment1.Accepted = true;
comment1.Save();
break;
case "second":
var comment2 = new secondSql.Comment(id);
comment2.Accepted = true;
comment2.Save();
break;
case "third":
var comment3 = new thirdSql.Comment(id);
comment3.Accepted = true;
comment3.Save();
break;
}
我正在寻找一种方法让它像这样
/* some magic to dynamically change the connection string */
cmsSql.ConnectionString( getConnectionString(sitename) );
var comment = new cmsSql.Comment(id);
comment.Accepted = true;
comment.Save();
是否有支持此功能的ORM解决方案?
或者,
您知道使用当前ORM(Subsonic 2.x)做任何解决方法吗?
更新:我再添加一个例子
cmsSql.ConnectionString( DB_ConString_WebsiteABC );
var comment = new cmsSql.Comment(id);
comment.Accepted = true;
comment.Save();
/* some magic to dynamically change the connection string */
cmsSql.ConnectionString( DB_ConString_AnotherWebsiteThatSimilarToABC );
var comment = new cmsSql.Comment(id);
comment.Accepted = true;
comment.Save(); // saved to another database
答案 0 :(得分:1)
我不知道亚音,但在LINQ-to-SQL中你可以编写一个ContextFactory,它使用不同的连接字符串创建上下文。
static class ContextFactory
{
public static MyDataContext CreateMyDataContent(string sitename)
{
var context;
switch(sitename){
case "first":
context = new MyDataContext ("connection string");
case "second":
// and so on
}
return context;
}
}
连接字符串本身你可以硬编码或从配置文件读取,或从你想要的任何地方读取: - )
答案 1 :(得分:1)
如果您只需要同时管理一个站点的CMS,我将使用单个SubSonic提供程序,并根据此示例更改静态DefaultConnectionString属性:
http://www.stevetrefethen.com/blog/SettingSubsonicsconnectionstringatruntime.aspx
答案 2 :(得分:0)
你到底想要什么?
在应用程序启动时设置连接字符串一次(但以编程方式)?
或者,您是否希望在应用程序运行时更改连接字符串,例如“仅运行第二个数据库的查询”?
如果是第一种情况(一次申请开始时):
我不知道Subsonic,但NHibernate可以做到这一点。
var cfg = new Configuration();
// set connectionstring programmatically
cfg.Properties["connection.connection_string"] = getConnectionString(sitename);
cfg.Configure();
cfg.AddAssembly( ... );
ISessionFactory sf = cfg.BuildSessionFactory();
答案 3 :(得分:0)
由于您在ConnectionStrings
文件中保存了所有web.config
,为什么不直接从connectionStrings Collection
获取适合您当前网站名称的内容?
ConfigurationManager.ConnectionStrings[sitename].ConnectionString;
OR
将连接保存回数据库(您可能需要加密以保证自己的安全)
所以你不要在web.config
硬编码它们,你只需存储该数据库的连接,现在..一个查询可以通过过滤网站名称解决整个问题 - 一个小逻辑类可以做到这一点您的
SELECT connection FROM tblConnections WHERE siteName = 'first'
希望这会有所帮助。
答案 4 :(得分:0)
您基本上要求的是多租户申请。
使用相同业务逻辑和用户界面的相同应用程序(您的CMS)将根据您正在操作的客户/上下文/公司/ 租户而有所不同。
在您的情况下,您正在进行'单一应用程序,隔离数据库'多租户。那就是你有一个应用程序,每个租户都有自己的数据库,与其他租户隔离。 (其他选项包括使用密钥隔离记录的共享数据库,例如所有表上的“TENANT_ID”,以及where子句将其过滤掉)。
在NHibernate中,您可以通过使用由唯一标识符(例如站点ID)标识的多个会话工厂(每个租户一个)来实现此目的。
确定要使用的网站ID可以通过多种方式完成。我们的应用程序基于主机名,但如果您是从单个站点进行操作,但想要切换上下文,则可以从“站点选择器”的下拉框中将其作为表单域进行。
对于SubSonic我相信你也可以做多个数据库 - 但是在他们之间交换我不知道该怎么做。