【问题标题】:asp.net, ExecuteReader requires an open and available Connectionasp.net,ExecuteReader 需要一个开放且可用的连接
【发布时间】:2014-09-15 05:25:39
【问题描述】:

我在一个方法上有这个代码:

DataGrid2.DataSource = Show1(Convert.ToInt32(Request.QueryString["Cr"]));
DataGrid2.DataBind();

这是分配给数据源的 show 方法:

static SqlConnection sqlConntest = new SqlConnection( ConfigurationSettings .AppSettings["conn"].ToString ());

public static SqlDataReader Show1(int cr)
 {
   SqlDataReader dr;
                SqlCommand cmd = new SqlCommand();
                cmd.Connection = sqlConntest;
                cmd.CommandType = CommandType.StoredProcedure;
                cmd.CommandText = "sp1";
                cmd.Parameters.Add("@Cr", SqlDbType.Int);
                cmd.Parameters["@Cr"].Value = crewID;
 sqlConntest.Open();
                dr = cmd.ExecuteReader();

                return dr;
}

当我运行程序时,我收到错误消息:

“ExecuteReader 需要一个打开且可用的连接。连接的当前状态为关闭”

为什么会发生这种情况,我该如何解决? 谢谢。

【问题讨论】:

  • sqlConntest.open(); 在 ExecuteReader 之前?
  • 也许我投票太早了,无法关闭重复。但是,另一个问题可能还是有用的,因为您还在 ASP.NET 中使用静态连接。不确定它是否能解决您的问题。
  • @Pyram 是的,您将在 使用后打开连接。因此,我的评论指出之前
  • @pyram:也使用using-statement 来尽快关闭连接。您还应该使用using 处理SqlDataReaderSqlCommand
  • @pyram:我认为这是由于现在连接在此方法中关闭(这很好)。但是由于您使用数据读取器作为在方法之外使用的数据源(在DataGrid2.DataBind()),您会遇到异常。我会简单地使用SqlDataAdapter 来填充DataTable,将其返回并用作DataSource。它只是一个内存中的对象,不需要打开连接。

标签: asp.net executereader


【解决方案1】:

现在我重新打开了这个问题,因为我的 proposed duplicate 可能会有所帮助并且是相关的,但似乎不是完全重复的。我将在此处发布我们的 cmets:

在 ASP.NET 中使用静态连接通常不是一个好主意,如果使用默认启用的连接池则更是如此。

你:“我已经从 sqlconnection 中删除了静态属性,但我仍然得到错误

也使用using-statement 来始终尽快关闭连接。您还应该使用using 处理SqlDataReaderSqlCommand

您:“我添加了 using 但现在我收到错误“读取器关闭时对 FieldCount 的尝试无效错误”

我认为这是由于现在连接将在此方法中关闭(这很好)。但是您将数据读取器用作DataSource 用于GridView,数据读取器是需要与数据库建立开放连接的流。它在DataGrid2.DataBind() 的方法之外使用。因此你得到了例外。

我会简单地使用SqlDataAdapter 来填充DataTable,将其返回并用作DataSource。它只是一个不需要打开连接的内存对象:

public static DataTable Show1(int cr)
{
    DataTable table = new DataTable();
    using (var con = new SqlConnection(ConfigurationSettings.AppSettings["conn"].ToString()))
    using (var cmd = new SqlCommand("sp1", con) { CommandType = CommandType.StoredProcedure })
    using (var da = new SqlDataAdapter(cmd))
        da.Fill(table);  // Fill opens the connection automatically
    return table;
}

【讨论】:

  • 嗨蒂姆,我用你的答案修改了代码,我得到了错误:“无法将类型'System.Data.DataRowView'转换为'System.Data.Common.DbDataRecord'”...... ....我该如何解决这个问题?
  • 然后你有代码将 GridViewRow.DataItem 转换为 DbDataRecord 而不是 DataRowView。我假设它在 RowDataBound 中。
  • 问题出在 DataGrid2_ItemDataBound 事件上。一旦这个事件被触发,就会调用一个方法,并且该方法有另一个 sql 连接,但它没有 sqlConnection.Open();这就是为什么我收到错误“ExecuteReader 需要一个打开且可用的连接。连接的当前状态已关闭”。所以我没有更改 SqlDataReader 代码。我刚刚将 sqlConnection.Open() 添加到该方法中。我已将您的答案标记为已接受的答案。感谢大家的帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多