簡體   English   中英

在ONE DataAccess Layer中處理多個連接字符串

[英]Handling multiple connection strings in ONE DataAccess Layer

我有一個有趣的困境。 我目前有一個DataAccess層,它必須與多個域一起工作,並且每個域都有多個數據庫存儲庫,具體取決於所調用的存儲過程。 現在我只是使用SWITCH語句來確定運行應用程序的機器並從Web.config返回相應的連接字符串。 現在我有一個艱巨的任務,就是在同一個SQL服務器中處理多個數據庫存儲庫,而id就像根據調用的存儲過程動態確定連接字符串一樣。 也許我在想這個,但我無法理解我將如何應對這一點。

我要說的第一件事是你的設計可能存在缺陷,因為需要跨多個數據庫調用多個存儲過程並不常見。

但是,有許多選項可用,例如:

  1. 在web.config中存儲存儲過程的列表以及每個存儲過程的相應連接字符串,並在運行時檢索它們。
  2. 有一個列出存儲過程和連接字符串的集中表(因此web.config中只有一個連接字符串,只是指向存儲過程連接字符串中央表的連接字符串)。

這確實是一個有趣的挑戰。 從設計角度來看,這可以通過各種方式解決,但它們似乎都有點破碎。

那么在這種情況下唯一對我有用的事情就像:

在每個服務器上創建一個過程數據庫,並在此數據庫上具有調用實際過程的“接口”過程。

喜歡:

CREATE PROC pr_GetAddress
(
    @addressId int
)
AS
BEGIN
    exec pubs.dbo.pr_GetAddress @addressId
END

這樣您就可以保留現有代碼。

您可以使用代碼生成為“接口”過程創建sql語句。

加:

這只是讓我大吃一驚......為什么不使用Linq-to-Sql DataContext?

我剛剛在這里玩這個片段:

public class ExperimentalDataContext: DataContext
{
    public ExperimentalDataContext(string connectionString) : base(connectionString) { }

    public IExecuteResult ExecuteMethod(object instance, MethodInfo methodInfo, params object[] parameters)
    {
        return this.ExecuteMethodCall(instance, methodInfo, parameters);
    }

    [Function(Name = "dbo.fx_Levenstein", IsComposable = true)]
    public static System.Nullable<double> fx_Levenstein([Parameter(DbType = "NVarChar(255)")] string firstword, [Parameter(DbType = "NVarChar(255)")] string secondword)
    {
        using (ExperimentalDataContext context = new ExperimentalDataContext(GetConnectionString("your-connectionstring")))
        {
            return ((System.Nullable<double>)(context.ExecuteMethod(context, ((MethodInfo)(MethodInfo.GetCurrentMethod())), firstword, secondword).ReturnValue));
        }
    }

    private static string GetConnectionString(string key)
    {
        return ConfigurationManager.ConnectionStrings[key].ConnectionString;
    }
}

如果您必須繼續確定數據庫是存儲過程調用,那么在配置文件中,定義您自己的配置部分,將存儲過程名稱映射到連接字符串。 那將是最明確的,但需要維持。

您也可以將其集中到一個較小的目錄數據庫中,該數據庫存儲針對存儲過程名稱的連接字符串 - 然后您可以創建一個SQL腳本,通過查詢其他數據庫對象來自動保持信息的最新和正確(沒有拼寫錯誤或拼寫錯誤) 。

然后我會將其讀入內存(緩存它),以便您可以避免在應用程序的生命周期內多次調用此目錄數據庫。 繼續我可以推測出關於數據庫整體結構的小信息(忽略了這個結構如何通過的問題),我想這是一個可管理的解決方案。

您可以通過讓基本DAL類負責返回適合給定過程名稱的連接來改進此解決方案 - 因此任何代碼更改只需要在一個位置發生以返回不同的連接。 其余的代碼調用GetConnection("getCustomers")並幸福地忽略了細節。

如果您可以根據存儲過程名稱唯一性真正映射單個連接字符串,那么嘗試的一個有趣的事情是在應用程序啟動時動態發現連接字符串列表中可用的存儲過程並緩存映射。

看起來您可以使用允許您命名(分類)連接字符串的常規ConnectionStrings配置。 在代碼中的某個時刻,您專門調用存儲過程。 該調用是否也可以指定要使用的連接字符串的鍵? 即:報告,會員等

<connectionStrings>
    <add name="Reporting" connectionString="<your connection string>" ... />
    <add name="Member" connectionString="<another connection string>" ... />
</connectionStrings>

對DAL的調用可能如下所示:

var result = ExecStoredProcedure("Reporting", "up_SomeProcedure");

假設您的DAL只是一個試圖操縱幾個不同數據庫的數據的程序集。 我建議,將代碼拆分為每個數據庫的單獨程序集。 然后,您可以獲得每個程序集的特定配置信息,代碼將只查看正在執行的程序集的特定配置信息。

例如,假設您有一個Movies數據庫和一個Books數據庫。 您將創建一個知道如何操作電影數據庫中的數據的庫,並且創建,編輯和查詢電影所需的所有代碼和存儲過程都將在該庫中。 該庫將擁有自己的配置信息,包括數據庫的連接字符串。

同樣,為了與您的圖書數據庫進行交互,您將擁有一個單獨的庫,其中包含用於創建,編輯和查詢有關圖書的信息的所有存儲過程。 同樣,這將擁有它自己的配置信息,包括連接字符串。

這種方法可以靈活地添加更多數據源,並相互獨立地配置它們。

如果您願意,您當然可以擁有另一個庫來處理可能需要訪問這兩個數據庫的事務,並且可以引用前面提到的庫中的代碼。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM