Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# ExecuteReader需要打开且可用的连接。连接';的当前状态正在连接_C#_.net_Sql Server_Ado.net_Database Connection - Fatal编程技术网

C# ExecuteReader需要打开且可用的连接。连接';的当前状态正在连接

C# ExecuteReader需要打开且可用的连接。连接';的当前状态正在连接,c#,.net,sql-server,ado.net,database-connection,C#,.net,Sql Server,Ado.net,Database Connection,当尝试通过ASP.NET online连接到MSSQL数据库时,当两个或多个用户同时连接时,我将获得以下信息: ExecuteReader需要打开且可用的连接。连接的当前状态为“正在连接” 该站点在我的本地主机服务器上运行良好 这是粗略的代码 public Promotion retrievePromotion() { int promotionID = 0; string promotionTitle = ""; string promotionUrl = "";

当尝试通过ASP.NET online连接到MSSQL数据库时,当两个或多个用户同时连接时,我将获得以下信息:

ExecuteReader需要打开且可用的连接。连接的当前状态为“正在连接”

该站点在我的本地主机服务器上运行良好

这是粗略的代码

public Promotion retrievePromotion()
{
    int promotionID = 0;
    string promotionTitle = "";
    string promotionUrl = "";
    Promotion promotion = null;
    SqlOpenConnection();
    SqlCommand sql = SqlCommandConnection();

    sql.CommandText = "SELECT TOP 1 PromotionID, PromotionTitle, PromotionURL FROM Promotion";

    SqlDataReader dr = sql.ExecuteReader();
    while (dr.Read())
    {
        promotionID = DB2int(dr["PromotionID"]);
        promotionTitle = DB2string(dr["PromotionTitle"]);
        promotionUrl = DB2string(dr["PromotionURL"]);
        promotion = new Promotion(promotionID, promotionTitle, promotionUrl);
    }
    dr.Dispose();
    sql.Dispose();
    CloseConnection();
    return promotion;
}
我可以知道可能出了什么问题以及如何修复它吗

编辑:别忘了,我的连接字符串和连接都是静态的。我相信这就是原因。请告知

public static string conString = ConfigurationManager.ConnectionStrings["dbConnection"].ConnectionString;
public static SqlConnection conn = null;

首先很抱歉只发表评论,但我几乎每天都会发布类似的评论,因为许多人认为将ADO.NET功能封装到DB类中是明智的(10年前我也是这样)。大多数情况下,他们决定使用静态/共享对象,因为这似乎比为任何操作创建新对象要快

就性能和故障安全而言,这既不是一个好主意

不要在连接池的区域内偷猎 ADO.NET在内部管理数据库管理系统的底层连接有一个很好的理由:

实际上,大多数应用程序只使用一种或几种不同的方法 连接的配置。这意味着在应用过程中 执行时,许多相同的连接将被重复打开和关闭 关闭为了最小化打开连接的成本,ADO.NET使用 称为连接池的优化技术

连接池减少了创建新连接的次数 必须打开。池方保留物理层的所有权 连接。它通过保持一组活动的连接处于活动状态来管理连接 每个给定连接配置的连接。每当用户 调用打开连接时,池处理程序将查找可用的 池中的连接。如果池连接可用,它将 将其返回给调用方,而不是打开新连接。当 应用程序在连接上调用Close,池程序将其返回给 活动连接的池集,而不是关闭它。一旦 连接返回到池中,即可在 下一个开放电话

因此,显然没有理由避免创建、打开或关闭连接,因为实际上它们根本没有被创建、打开和关闭。这是连接池“仅”知道何时可以重用或不重用连接的标志。但这是一个非常重要的标志,因为如果一个连接“正在使用”(连接池假定),那么必须打开一个新的物理连接,并且到DBMS的连接非常昂贵

因此,您没有获得任何性能改进,相反。如果达到指定的最大池大小(默认值为100),甚至会出现异常(打开的连接太多…)。因此,这不仅会极大地影响性能,而且还会成为严重错误的来源和(不使用事务)数据转储区域

如果您使用的是静态连接,那么您正在为尝试访问此对象的每个线程创建一个锁。ASP.NET本质上是一个多线程环境。因此,这些锁很有可能导致性能问题。实际上,迟早你会遇到许多不同的异常(比如你的ExecuteReader需要一个开放的可用连接)

结论

  • 不要重用连接或任何ADO.NET对象
  • 不要将它们设置为静态/共享(在VB.NET中)
  • 始终创建、打开(在连接的情况下)、使用、关闭并在需要的地方处置它们(例如,在方法中)
  • 使用以隐式方式处置和关闭(在连接的情况下)
这不仅适用于连接(尽管最值得注意)。每个实现的对象都应该在
System.Data.SqlClient
名称空间中处理(最简单)

所有这些都是针对封装和重用所有对象的自定义DB类的。这就是为什么我评论说它是垃圾。这只是一个问题的根源


编辑:以下是您的
检索升级
方法的可能实现:

public Promotion retrievePromotion(int promotionID)
{
    Promotion promo = null;
    var connectionString = System.Configuration.ConfigurationManager.ConnectionStrings["MainConnStr"].ConnectionString;
    using (SqlConnection connection = new SqlConnection(connectionString))
    {
        var queryString = "SELECT PromotionID, PromotionTitle, PromotionURL FROM Promotion WHERE PromotionID=@PromotionID";
        using (var da = new SqlDataAdapter(queryString, connection))
        {
            // you could also use a SqlDataReader instead
            // note that a DataTable does not need to be disposed since it does not implement IDisposable
            var tblPromotion = new DataTable();
            // avoid SQL-Injection
            da.SelectCommand.Parameters.Add("@PromotionID", SqlDbType.Int);
            da.SelectCommand.Parameters["@PromotionID"].Value = promotionID;
            try
            {
                connection.Open(); // not necessarily needed in this case because DataAdapter.Fill does it otherwise 
                da.Fill(tblPromotion);
                if (tblPromotion.Rows.Count != 0)
                {
                    var promoRow = tblPromotion.Rows[0];
                    promo = new Promotion()
                    {
                        promotionID    = promotionID,
                        promotionTitle = promoRow.Field<String>("PromotionTitle"),
                        promotionUrl   = promoRow.Field<String>("PromotionURL")
                    };
                }
            }
            catch (Exception ex)
            {
                // log this exception or throw it up the StackTrace
                // we do not need a finally-block to close the connection since it will be closed implicitely in an using-statement
                throw;
            }
        }
    }
    return promo;
}
publicpromotionretrievepromotion(int-promotionID)
{
促销促销=空;
var connectionString=System.Configuration.ConfigurationManager.ConnectionStrings[“MainConnStr”].connectionString;
使用(SqlConnection连接=新的SqlConnection(connectionString))
{
var queryString=“从促销中选择促销ID、促销标题、促销URL,其中促销ID=@PromotionID”;
使用(var da=new-SqlDataAdapter(queryString,connection))
{
//您也可以改用SqlDataReader
//请注意,不需要处理DataTable,因为它不实现IDisposable
var tblPromotion=新数据表();
//避免SQL注入
da.SelectCommand.Parameters.Add(“@PromotionID”,SqlDbType.Int);
da.SelectCommand.Parameters[“@PromotionID”].Value=PromotionID;
尝试
{
connection.Open();//在这种情况下不一定需要,因为DataAdapter.Fill不需要
da.填充(TBL推动);
如果(tblPromotion.Rows.Count!=0)
{
var promoRow=tblPromotion.Rows[0];
促销=新促销()
{
promotionID=promotionID,
promotionTitle=PromotionRow.Field(“promotionTitle”),
promotionUrl=promotorw.Field(“promotionUrl”)
};
}
}
捕获(例外情况除外)
{
//记录此异常或将其抛出StackTrace
//我们不需要finally块来关闭连接,因为它将
public class DbHelper : DbHelperCore
{
    public DbHelper()
    {
        Connection = null;
        Transaction = null;
    }

    public static DbHelper instance
    {
        get
        {
            if (HttpContext.Current is null)
                return new DbHelper();
            else if (HttpContext.Current.Items["dbh"] == null)
                HttpContext.Current.Items["dbh"] = new DbHelper();

            return (DbHelper)HttpContext.Current.Items["dbh"];
        }
    }

    public override void BeginTransaction()
    {
        Connection = new SqlConnection(Entity.Connection.getCon);
        if (Connection.State == System.Data.ConnectionState.Closed)
            Connection.Open();
        Transaction = Connection.BeginTransaction();
    }
}