全局变量问题

时间:2016-03-08 04:58:40

标签: c# asp.net web-config connection-string

在我的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; "/>

在登录时,用户必须选择适当的数据库,然后根据所选的数据库软件连接到所需的数据库。

我创建了一个全局类,它将用户连接到所需的数据库,如

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上运行它并且多个用户访问它时,主要问题就开始了。

如果User1连接到connect15-16,一段时间后user2连接到connect16-17,那么Connection变量overite的值和User1连接到connect16-17 自动。 我不能为不同的用户使用不同的变量,因为在我的应用程序中我使用了Connection变量,如下所示:

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

3 个答案:

答案 0 :(得分:1)

  

在ASP.Net中,静态变量具有应用范围,但不可能   无法实例化。因此它会导致并发问题   你现在面对。它将更适合Windows应用程序。

如果您需要为单个用户分享跨页面数据Session,那么您将可以访问它。它可以帮助您存储和检索用户的值。但在你的情况下我不会喜欢会话来存储连接或connectionString,因为它为攻击者打开了一扇大门

我想建议对Connections类进行一些修改,以便您可以在整个应用程序中访问Connection。 [假设您在会话中拥有用户名/ Id]

 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从系统A访问USR0001然后调用静态方法,如下所示:

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

UserId用户2从系统B访问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()

答案 1 :(得分: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);
    }
}  
  

保存在变量中返回的SqlConnection对象供以后使用

答案 2 :(得分:0)

这是静态的正常行为。因此,如果要解决覆盖问题,则需要为不同用户提供不同的连接。