亚音速:动态连接

时间:2009-06-09 05:59:15

标签: .net winforms subsonic

我有一个古老的混乱,我正在尝试使用亚音速铲入层。麻烦的是,我有这个场景:

当Hal登录时,他的登录使用数据库X查找数据,数据库Y用于他的帐户,数据库Z用于他的联系人。

当Barry登录时,他的登录名使用数据库X代表查询数据,数据库Q代表他的账户,数据库R代表他的联系人。

X,Y,Z,Q和R都在同一台服务器上。 Y有一个与Q相同的模式,并且Z与R具有相同的模式。不要让我开始研究这是多么愚蠢:)

我必须让我的.NET Winforms App(使用亚音速)指向正确的数据库。

据我所知,我将不得不弄脏SubSonic来源(并在每个亚音速版本中保持这些变化),因此它可以接受参数而不是使用app.config。任何人都可以看到替代品吗?

5 个答案:

答案 0 :(得分:2)

  
    
      

我从未认为'SharedDbConnectionScope'很容易或适合我的应用程序

    
  

然而那就是答案不是吗?这就是为什么我们把它放在那里 - 是的,我已经听到你的连接请求变化,我已经建立了它,因为我一直在告诉你我们拥有的每个线程。

动态改变连接是我们长期以来的一个要求,我们在很长一段时间内将它添加到了那里 - 据我所知,它就像一个魅力。

对于SubSonic 3,我会插入大约10种不同的方式,您可以随时根据需要随意更改数据库连接。

答案 1 :(得分:1)

您不需要修改源,您应该只能使用多个提供程序与不同的数据库进行通信,并在运行时在它们之间切换。 看看下面的问题,看看如何做到这一点:

Separate Read/Write Connection for SubSonic

答案 2 :(得分:1)

  1. Subsonic可以为多个数据库创建dal。 只需添加一个提供程序,引用另一个连接字符串到您的app.config。 修改每个提供程序的名称空间。
  2. 现在您应该可以访问:         My.Namespace.R ...         My.Namespace.X ...

    1. 您可以轻松快速更改连接:

      using (SharedDbConnectionScope scope = new SharedDbConnectionScope("new connectionstring "))
      {
      }
      
    2. 如果一次不需要多个连接,也可以这样做。 我们使用它来注销并登录到另一台服务器(另一个副作用是,你不需要app / web.config。

      在此处找到此示例:http://www.digvijay.eu/post/2008/10/30/SubSonic-Trick-Specify-connection-string-at-runtime!.aspx

      每次调用InitSubsonic时,连接都会改变。

      public class MySubsonicProvider
      {
      
          private static bool _bIsInitialized = false;
      
          public static void InitSubsonic(string server, string schema, string user, string password)
          {
      
              DataService.Providers = new DataProviderCollection();
      
              // here you can get settings from anywhere and make up a connection string :)
              MyDataProvider provider = new MyDataProvider("Server={0};Database={1};Uid={2};Password={3}", server, schema, user, password);
              DataService.Providers.Add(provider);
              DataService.Provider = provider;
      
              _bIsInitialized = true;
      
              // Clear cached values
              ClearSubSonicCache();
      
          }
      
          public class MyDataProvider : MySqlInnoDBDataProvider
          {
      
              private string _server;
              private string _schema;
              private string _user;
              private string _password;
      
              public string Server { get { return _server; } }
              public string Schema { get { return _schema; } }
              public string User { get { return _user; } }
              public string Password { get { return _password; } }
      
              public MyDataProvider(string connectionString, string server, string schema, string user, string password)
              {
                  DefaultConnectionString = String.Format(connectionString, server, schema, user, password);
      
                  _server = server;
                  _schema = schema;
                  _user = user;
                  _password = password;
      
              }
      
              public override string Name
              {
                  get { return "MyDataProvider"; }
              }
      
          }
      }
      

答案 3 :(得分:1)

谢谢你们。我已经有多个提供商,但不知道如何在运行时设置它们(我已经搜索过这个论坛。必须使用错误的关键字)。

SharedDBConnectionScope似乎非常适合在飞行中使用,但似乎并不是为整个用户会话设置提供程序。

所以我根据你上面的答案做了更多的搜索,并提出了以下解决方案:

1)为查找,帐户和联系人添加三个提供程序,并生成DAL。

2)将其添加到DAL:

public static void SetProvider(string strProvider,string strConnectionString)
{
    DataService.GetInstance(strProvider).DefaultConnectionString = 
                                                     strConnectionString;
}

3)一旦我的应用程序确定了用户使用的数据库,例如

,就可以在登录时调用它
MyDAL.SSProvider.SetProvider("Lookups", 
            "server=10.123.456.78;port=3306;uid=whatever;pwd=blah;database=X")

MyDAL.SSProvider.SetProvider("Accounts", 
      "server=10.123.456.78;port=3306;uid=whatever;pwd=blah;database=Y")

MyDAL.SSProvider.SetProvider("Contacts",    
               "server=10.123.456.78;port=3306;uid=whatever;pwd=blah;database=Z")

关闭它。

答案 4 :(得分:1)

另一个动态更改提供程序的示例(在运行时)。 这个从一个数据库读取项目并将它们保存到另一个数据库。

使用:

CopyToAnotherDB<Dock>(Dock.Columns.Id, Dock.BarcodeStringColumn);

方法:

    public static void CopyToAnotherDB<E>(string identifierColumnName, TableSchema.TableColumn fakeDirtyColHack)
        where E : ActiveRecord<E>, new()
    {
        SqlQuery q = new Select().From<E>();
        q.ProviderName = SERVU_PROVIDER;
        IList<E> list = q.ExecuteTypedList<E>();

        string connStr = ConfigurationManager.ConnectionStrings[ARCHIVE_PROVIDER].ConnectionString;
        using (SharedDbConnectionScope scope = new SharedDbConnectionScope(connStr))
        {
            foreach (E item in list)
            {
                int itemID = (int)item.GetColumnValue(identifierColumnName);
                SqlQuery qry = new Select(identifierColumnName).From<E>().Where(identifierColumnName).IsEqualTo(itemID);
                int recCount = qry.GetRecordCount();
                E obj = item.Clone();

                obj.IsNew = recCount == 0; //determines if adding or updating
                obj.IsLoaded = !obj.IsNew; //determines if adding or updating
                obj.DirtyColumns.Add(fakeDirtyColHack);
                obj.Save();
            }
        }
    }