我的SqlConnection代码有什么问题?

时间:2017-04-28 07:14:56

标签: c# asp.net sql-server

在我的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上运行它并且多个用户通过ip从不同的计算机访问它时,主要问题就开始了。

如果User1连接到connect15-16,一段时间后user2连接到connect16-17,则Connection变量overite的值和User1自动连接connect16-17。

要解决此问题,我对Connections类进行了一些更改,并使用dictionary为不同用户创建单独的连接。这是我的新Connections课程

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["UserName"].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);
                }
            }

        }
    }

现在我到处都使用以下代码来打开和关闭连接。

Connections.Connection[UserName].Open();
Connections.Connection[UserName].Close();

我的问题已成功解决但新问题已开始。我的软件性能非常低下。一些专家告诉我,这是因为我的Connections类,因为有很多处理过的连接会占用太多内存。

请建议我Connections课程需要哪些更改才能获得更好的效果。

1 个答案:

答案 0 :(得分:3)

对您的代码做出反应,废弃设计并根据需要创建连接,然后在完成后立即将其销毁。

示例:

using(var connection = new SqlConnection(/*connection string from app/web.config*/))
{
  // use the connection
}

为什么?

ADO.NET for Sql Server使用水下连接池。创建新的SqlConnection实例时,SqlConnection个实例会自动重用池中的可用连接。因此,尝试重用SqlConnection实例不会带来真正的性能提升。有关如何通过ADO.NET管理池的更多信息,请参阅Sql Server Connection Pooling

建议您在需要时将SqlConnection包裹在using块中,以便在完成后立即处理。保持SqlConnection短暂的生命。这样可以确保没有连接保持打开时间更长,并确保通过尝试共享/重用连接不会出现竞争条件。

  

我希望如果有人向我解释一个例子......

重构代码的示例。将Connections类替换为ConnectionFactory,请注意内存中没有持久状态。它创建一个新连接并返回它,仅此而已。消费者在using块内完成连接并处理它。

ConnectionFactory.cs

public static class ConnectionFactory
{
    public static SqlConnection Create(string Name)
    {
        // todo: add some checking to ensure that Name parameter is not null/empty and that there is a corresponding entry in the app/web config
        return new SqlConnection(System.Web.Configuration.WebConfigurationManager.ConnectionStrings[Name].ConnectionString);
    }
}

SomeCallingMethod.cs

public void GetSomethingFromStore()
{
    using(var connection = ConnectionFactory.Create("connect15-16"))
    {
        // do some db work
    }
}