我在方法上有这个代码:
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需要一个开放且可用的连接。连接的当前状态已关闭”
为什么会发生这种情况,我该如何解决这个问题? 感谢。
答案 0 :(得分:1)
现在我已经重新打开了这个问题,因为我的proposed duplicate可能会有所帮助并且相关,但似乎并不完全重复。我会在这里发表评论:
在ASP.NET中使用静态连接通常不是一个好主意,如果使用默认启用的连接池,则更是如此。
您:“我已从sqlconnection中删除了静态属性,但仍然出现错误”
还可以使用using
-statement来尽快关闭连接。您还应该将SqlDataReader
和SqlCommand
与using
一起处理。
你:“我添加了使用但现在我收到错误”当阅读器关闭时对FieldCount的无效尝试错误“”
我认为这是由于现在连接将在此方法中关闭(这很好)。但是对DataSource
使用datareader作为GridView
,datareader是需要与数据库打开连接的流。它在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;
}