2016-03-08 97 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

我非常了解,请告诉我解决方案。 –