Sql连接中的连接打开和关闭问题

时间:2018-04-18 04:54:47

标签: c# asp.net connection-pooling

找到许多解决方案但不适合我的方案。

问题:我正在研究在asp.net下构建的在线软件。从过去的几天开始,我的应用程序运行缓慢,有些时候崩溃。当我试图找到问题时,我发现连接池有连接处于休眠模式。我知道有些连接是开放的但未正确关闭。在下面我将向您展示我的DBManager文件。请查看它,并给我一些建议,可以帮助我正确打开和关闭我的连接。

注意:当用户快速使用应用程序时,会抛出连接异常。 我的应用程序使用许多数据输入操作符,它们是速度类型。并且一次又一次地在页面之间移动。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.SqlClient;
using System.Data;
using System.Configuration;

/// <summary>
/// Summary description for DBManager
/// </summary>
public class DBManager
{
    public static SqlConnection _connection;
    public static SqlCommand _command;
    public static SqlDataReader _reader;
    public static SqlDataAdapter _dataAdapter;
    public List<SqlParameter> Parameters = new List<SqlParameter>();
    public static string _connectionString = "DefaultConnectionString";
    SqlTransaction _sqlTransaction;

    public DBManager()
    {
        // TODO: Add constructor logic here
    }

    public DBManager(SqlTransaction sqlTransaction = null)
    {
        _sqlTransaction = sqlTransaction;
    }

    public DBManager(string connectionStringName, SqlTransaction sqlTransaction = null)
    {
        _connectionString = connectionStringName;
        _sqlTransaction = sqlTransaction;
    }

    public static string CreateConnection()
    {
        string ConnectionString = ConfigurationManager.ConnectionStrings[_connectionString].ConnectionString;
        _connection = new SqlConnection(ConnectionString);
        _connection.Open();
        return "0";
    }

    public static void CloseConnection()
    {
        _connection.Close();
        _connection.Dispose();
    }

    public void AddParameter(string parameterName, object value, SqlDbType sqlDbType, int size)
    {
            SqlParameter parameter = new SqlParameter(parameterName, sqlDbType, size);
            parameter.Value = value;

            Parameters.Add(parameter);      
    }

    public void AddParameter(string parameterName, object value, SqlDbType sqlDbType, int size,ParameterDirection parameterDirection)
    {
        SqlParameter parameter = new SqlParameter(parameterName, sqlDbType, size);
        parameter.Value = value;
        parameter.Direction = parameterDirection;
        Parameters.Add(parameter);
    }

    public void AddParameter(string parameterName, object value)
    {
        SqlParameter parameter = new SqlParameter(parameterName,value);
        Parameters.Add(parameter);
    }

    public int ExecuteNonQuery(string procedureName)
    {
        int result = 0;

        try
        {
           // if (CreateConnection() == "1") { return 0; }
            CreateConnection();
            _command = new SqlCommand(procedureName, _connection);
            if (Parameters.Count != 0)
            {
                for (int i = 0; i < Parameters.Count; i++)
                {
                    _command.Parameters.Add(Parameters[i]);
                }

            }
            _command.CommandType = CommandType.StoredProcedure;
            result = _command.ExecuteNonQuery();
            CloseConnection();
            _command.Dispose();
        }
        catch (Exception)
        {
            CloseConnection();
            _command.Dispose();
            throw;
        }

        return result;
    }

    public SqlDataReader ExecuteReader(string procedureName)
    {
        SqlDataReader reader;

        try
        {
            CreateConnection();
           // if (CreateConnection() == "1") { return reader=0; }
            _command = new SqlCommand(procedureName, _connection);

            if (Parameters.Count != 0)
            {
                for (int i = 0; i < Parameters.Count; i++)
                {
                    _command.Parameters.Add(Parameters[i]);
                }

            }

            _command.CommandType = CommandType.StoredProcedure;
            reader = _command.ExecuteReader(CommandBehavior.CloseConnection);
            CloseConnection();
            _command.Dispose();
        }
        catch (Exception)
        {
            CloseConnection();
            _command.Dispose();
            throw;
        }

        return reader;
    }

    public DataSet ExecuteDataSet(string procedureName)
    {
        DataSet dataSet = new DataSet();

        try
        {
            CreateConnection();
            _command = new SqlCommand(procedureName, _connection);

            if (Parameters.Count != 0)
            {
                for (int i = 0; i < Parameters.Count; i++)
                {
                    _command.Parameters.Add(Parameters[i]);    
                }

            }

            _command.CommandType = CommandType.StoredProcedure;
            _dataAdapter = new SqlDataAdapter(_command);
            _dataAdapter.Fill(dataSet);
            CloseConnection();
            _command.Dispose();
            _dataAdapter.Dispose();
        }
        catch (Exception)
        {
            CloseConnection();
            _dataAdapter.Dispose();
            _command.Dispose();
            throw;
        }
           return dataSet;
    }

    public DataTable ExecuteDataTable(string procedureName)
    {
        DataTable dataTable = new DataTable();

        try
        {
            CreateConnection();
            _command = new SqlCommand(procedureName, _connection);

            if (Parameters.Count != 0)
            {
                for (int i = 0; i < Parameters.Count; i++)
                {
                    _command.Parameters.Add(Parameters[i]);
                }
            }

            _command.CommandType = CommandType.StoredProcedure;
            _dataAdapter = new SqlDataAdapter(_command);
            _dataAdapter.Fill(dataTable);
            CloseConnection();
            _command.Dispose();
            _dataAdapter.Dispose();
        }
        catch (Exception)
        {
            CloseConnection();
            _dataAdapter.Dispose();
            _command.Dispose();
            throw;
        }

        return dataTable;
    }

    public string ExecuteScalar(string procedureName)
    {
        string result = "";

        try
        {
            CreateConnection();
            _command = new SqlCommand(procedureName, _connection);

            if (Parameters.Count != 0)
            {
                for (int i = 0; i < Parameters.Count; i++)
                {
                    _command.Parameters.Add(Parameters[i]);
                }

            }

            _command.CommandType = CommandType.StoredProcedure;
            result = _command.ExecuteScalar().ToString();
            CloseConnection();
            _command.Dispose();
        }
        catch (Exception)
        {
            CloseConnection();
            _command.Dispose();
            throw;
        }

        return result;
    }
}    

例外情况是:

  

InnerException System.InvalidOperationException:ExecuteReader需要一个开放且可用的连接。连接的当前状态是连接   在System.Data.SqlClient.SqlConnection。

     

InnerException System.InvalidOperationException:无效的操作。连接已关闭   在System.Data.ProviderBase.DbConnectionClosed。

     

InnerException System.NullReferenceException:未将对象引用设置为对象的实例。

1 个答案:

答案 0 :(得分:5)

你一共做错了,你应该创建连接但不应该打开它,你应该在需要时打开并关闭它

我建议也删除此功能,只使用using

    public static string CreateConnection()
    {

   string ConnectionString = ConfigurationManager.ConnectionStrings[_connectionString].ConnectionString;
        _connection = new SqlConnection(ConnectionString);
           //remove this line 
        //_connection.Open();
        return "0";
    }

你也不需要这个功能

 public static void CloseConnection()
    {
        _connection.Close();
        _connection.Dispose();
    }

按照建议使用帮助

我建议的最佳方法是始终使用using并处理连接,如下所示

using(SqlConnection con = new SqlConnection() )
{
}

如果你担心它会创建太多的对象,那么与数据库的信息连接汇集意味着你可以在连接字符串中指定连接池信息,这样你就不必担心在创建连接对象时建立连接

<add name="sqlConnectionString" connectionString="Data 
Source=mySQLServer;Initial Catalog=myDatabase;Integrated 
Security=True;Connection Timeout=15;Connection Lifetime=0;Min Pool Size=0;Max 
Pool Size=100;Pooling=true;" />

以上是关注池的连接字符串

示例代码,这就是我在poroject中的表现,如果你看到代码我每次都使用using

来反对连接对象
public class DbHelper
{
    #region Private methods

    private static OracleConnection GetConnection()
    {
        string connectionString = DbConnectionString.ConnectionString;
        return new OracleConnection(connectionString);
    }

    private static OracleCommand GetCommand(OracleConnection connection, string commandText, OracleParameter[] param, bool isProcedure)
    {
        OracleCommand dbCommand = new OracleCommand();
        dbCommand.Connection = connection;
        dbCommand.CommandText = commandText;
        if (param != null)
            dbCommand.Parameters.AddRange(param);
        if (isProcedure)
            dbCommand.CommandType = CommandType.StoredProcedure;
        return dbCommand;
    }
    #endregion

    #region public methods
    public static DataTable GetDataTable(string commandText, OracleParameter[] odbcPrams, bool isProcedure = false)
    {
        DataTable dt = new DataTable();
        using (OracleConnection ODBCConn = GetConnection())
        {
            using (OracleCommand dbCommand = GetCommand(ODBCConn, commandText, odbcPrams, isProcedure))
            {
                ODBCConn.Open();
                OracleDataAdapter da = new OracleDataAdapter(dbCommand);
                da.Fill(dt);
            }
        }

        return dt;
    }
    #endregion
}