Любой ORM может программно изменить строку подключения во время выполнения? - PullRequest
3 голосов
/ 07 февраля 2011

Я создал свою собственную CMS для собственного использования.в настоящее время я уже запускаю 3 веб-сайта, используя мою CMS.и буду продолжать добавлять.

, поскольку все сайты всегда используют одну и ту же версию моей 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

Ответы [ 5 ]

1 голос
/ 04 марта 2011

Если вам нужно управлять CMS только для одного сайта одновременно, я бы использовал одного поставщика SubSonic и изменил бы статическое свойство DefaultConnectionString, как показано в этом примере:

http://www.stevetrefethen.com/blog/SettingSubsonicsconnectionstringatruntime.aspx

1 голос
/ 07 февраля 2011

Я не знаю о дозвуковых, но в LINQ-to-SQL вы могли бы написать ContextFactory, который создает контексты, используя разные строки подключения.читать из файла конфигурации или из любого другого места, где вы хотите: -)

0 голосов
/ 03 марта 2011

По сути, вы запрашиваете мультитенантное приложение.

Одно и то же приложение (ваша CMS), использующее ту же бизнес-логику и пользовательский интерфейс, будет отличаться в зависимости от того, на каком клиенте / контексте / компании / арендаторе вы работаете.

В вашей ситуации вы работаете с мультитенантным приложением «отдельное приложение, изолированная база данных». То есть у вас есть одно приложение, и у каждого арендатора есть своя собственная база данных, изолированная от других арендаторов. (Другие параметры включают общую базу данных, в которой записи изолированы с помощью ключа, такого как «TENANT_ID» во всех таблицах, и предложение where отфильтровывает их).

В NHibernate вы можете добиться этого, используя несколько фабрик сеансов (по одному на каждого арендатора), идентифицируемых уникальным идентификатором, таким как идентификатор сайта.

Выяснить, какой идентификатор сайта использовать, можно несколькими способами. Наше приложение основывает его на имени хоста, но если вы делаете это с одного сайта, но хотите переключить контексты, вы можете сделать это как поле формы из выпадающего списка «селектор сайтов».

Для SubSonic я считаю, что вы также можете создавать несколько баз данных, но я не знаю, как переключаться между ними.

0 голосов
/ 02 марта 2011

, так как все ваши ConnectionStrings сохранены в файле web.config, почему бы просто не взять то, что подходит вашему текущему названию веб-сайта непосредственно из connectionStrings Collection?

ConfigurationManager.ConnectionStrings[sitename].ConnectionString;

OR
сохранить соединения обратно в базу данных ( здесь вам может понадобиться шифрование для обеспечения безопасности ) так что вы не жестко закодировали их в web.config и просто сохраняете соединение с этой базой данных, теперь .. один запрос может решить всю проблему, отфильтровав имя веб-сайта - небольшой логический класс может сделать это за вас

SELECT connection FROM tblConnections WHERE siteName = 'first'

Надеюсь, это помогло.

0 голосов
/ 07 февраля 2011

Что именно вы хотите?
Задать строку подключения один раз (но программно) при запуске приложения?
Или вы хотите изменить строку подключения во время работы вашего приложения, например «выполнить только следующий запрос для базы данных номер два»?

Если это первый случай (один раз при запуске приложения):
Я не знаю Subsonic, но NHibernate может это сделать.

var cfg = new Configuration();

// set connectionstring programmatically
cfg.Properties["connection.connection_string"] = getConnectionString(sitename);
cfg.Configure();

cfg.AddAssembly( ... );
ISessionFactory sf = cfg.BuildSessionFactory();
...