2016-03-08 193 views
0

在我的web.config我宣佈基於不同的數據庫這樣全局變量問題

<add name="connect15-16" connectionString="Initial Catalog=Database15-16;User ID=sa;Password=pwd; "/> 
<add name="connect16-17" connectionString="Initial Catalog=Database16-17;User ID=sa;Password=pwd; "/> 
<add name="connect17-18" connectionString="Initial Catalog=Database17-18;User ID=sa;Password=pwd; "/> 
<add name="connect18-19" connectionString="Initial Catalog=Database18-19;User ID=sa;Password=pwd; "/> 
<add name="connect19-20" connectionString="Initial Catalog=Database19-20;User ID=sa;Password=pwd; "/> 

在登錄的時候很多的ConnectionStrings,用戶根據所選擇的數據庫軟件來選擇相應的數據庫,然後連接到所需數據庫。

我創建了這樣

public static class Connections 
{ 
    public static SqlConnection Connection {get; set;}  
    public static void Init(string Name) 
    {   
     Connection = new SqlConnection(System.Web.Configuration.WebConfigurationManager 
           .ConnectionStrings[Name].ConnectionString); 
    } 
} 

這是工作的罰款連接用戶所需的數據庫全局類。但是當我在localhost上運行它並且多個用戶訪問它時,主要問題就開始了。

如果用戶1連接到connect15-16和經過一段時間後用戶2連接到connect16-17然後連接可變overites的值和用戶1與自動connect16-17 連接。 因爲到處都在我的應用程序中使用這樣的連接變量,我不能使用不同的變量,針對不同的用戶:

Connections.Connection.Open(); 
Connections.Connection.Close(); 

回答

1

在ASP.Net中,靜態變量具有應用範圍,它不能被 無法實例化。因此,它會導致併發問題,您現在正面臨着 。它將更適合Windows應用程序。

如果您需要跨頁面共享單個用戶的數據,Session將是您可以訪問的最佳選擇。它可以幫助您存儲和檢索用戶的值。但在你的情況下我不會喜歡會話來存儲連接或connectionString,因爲它爲攻擊者打開了一扇大門。

我想建議對Connections類進行一些修改,以便跨應用程序訪問Connection。[假設你/標識在會話擁有的用戶名]

public static class Connections 
    { 
     private static Dictionary<string, SqlConnection> _Connection = new Dictionary<string, SqlConnection>(); 
     public static Dictionary<string, SqlConnection> Connection 
     { 
      get { return _Connection; } 
      set { _Connection = value; } 
     } 
     public static void Init(string Name) 
     { 
      string user=HttpContext.Current.Session["UserId"].ToString(); 
      if (!Connection.ContainsKey(user)) 
      { 
       Connection.Add(user, new SqlConnection(System.Web.Configuration.WebConfigurationManager.ConnectionStrings[Name].ConnectionString)); 
      } 
      else 
      { 
       if (Connection[user] == null) 
       { 
        Connection[user] = new SqlConnection(System.Web.Configuration.WebConfigurationManager.ConnectionStrings[Name].ConnectionString); 
       } 
      } 

     } 
    } 

使用方法:

UserId用戶1從系統訪問AUSR0001然後調用類的靜態方法以下:

Connections.Init("connect15-16"); // To init the connection 
    // This will add a connection to the Connection with key USR0001 

UserId用戶2從系統訪問是USR0045然後調用像下面的靜態方法:

Connections.Init("connect16-17"); // To init the connection 
// This will add a connection to the Connection with key USR0045 

因此,您將獲得用戶1和用戶2

獨立的連接當過您要使用的連接,您可以訪問它們通過下面的代碼行:

SqlConnection sqlCon = Connections.Connection["UserId"]; // this will be different for different users 

否則你可以直接調用這樣的訪問它們:Connections.Connection["UserId"].Open()

+0

你的意思是說,在每一頁上我必須改變我的代碼SqlConnection sqlCon = Connections.Connection [「UserId」]; sqlCon.Open();而不是Connections.Connection.Open(); –

+0

不需要你可以像這樣調用'open()''Connections.Connection [「UserId」]。Open()' –

+0

好的,謝謝,讓我檢查一下。 –

0

不要創建靜態變量,只是改變你的代碼如下

public class Connections 
{ 
    private SqlConnection Connection { get; set; } 
    public void Init(string Name) 
    { 
     Connection = GetInstance(Name); 
    } 

    private SqlConnection GetInstance(string Name) 
    { 
     return new SqlConnection(System.Web.Configuration.WebConfigurationManager.ConnectionStrings[Name].ConnectionString); 
    } 
} 

如果你想保持它的靜態比你可以按照如下

public class Connections 
{ 
    public static SqlConnection Init(string Name) 
    { 
     return new SqlConnection(System.Web.Configuration.WebConfigurationManager.ConnectionStrings[Name].ConnectionString); 
    } 
} 

保存在變量返回供以後使用

+0

對於非靜態字段,方法或屬性,需要一個對象引用:'Init()'內不能訪問'Connection' @ –

+0

@不幸運是正確的。靜態方法中不能訪問靜態變量。 –

+0

@ShaiwalTripathi我已經編輯了答案,現在應該可以正常工作 – mzh

0

這是靜態的正常行爲的SqlConnection對象。所以如果你想解決覆蓋問題,你需要爲不同的用戶建立不同的連接。

+0

你能描述一下嗎? –

+0

對於Static變量的內存分配將只有一次,所以無論何時從用戶處獲取輸入並將其分配給Connections類的Connection屬性,靜態成員的舊值都將被覆蓋。 – Babu

+0

我非常瞭解,請告訴我解決方案。 –