我对使用为什么我不能在同一代码中多次使用同一个SQLCommand实例有疑问?
我在这里尝试了代码并且它对gridview运行良好但是当我使用cmd.CommandText()
方法更改查询时它会一直说:
已经有一个与此命令关联的打开DataReader,必须先关闭它。
这是代码:
string cs = ConfigurationManager.ConnectionStrings["MyDB"].ConnectionString;
SqlConnection con = new SqlConnection(cs);
try
{
SqlCommand cmd = new SqlCommand();
cmd.Connection = con;
con.Open();
cmd.CommandText = "Select top 10 FirstName, LastName, Address, City, State from Customers";
GridView1.DataSource = cmd.ExecuteReader();
GridView1.DataBind();
cmd.CommandText = "SELECT TOP 10 COUNT(CreditLimit) FROM Customers";
int total = (int)cmd.ExecuteScalar();
TotalCreditLble.Text = "The total Credit :" + total.ToString();
}
catch(Exception exp)
{
Response.Write(exp.Message);
}
finally
{
con.Close();
}
答案 0 :(得分:5)
问题是您正在使用SqlCommand
对象通过command.ExecuteReader()
命令生成DataReader。虽然这是打开的,但您无法重复使用该命令。
这应该有效:
using (var reader = cmd.ExecuteReader())
{
GridView1.DataSource = reader;
GridView1.DataBind();
}
//now the DataReader is closed/disposed and can re-use command
cmd.CommandText = "SELECT TOP 10 COUNT(CreditLimit) FROM Customers";
int total = (int)cmd.ExecuteScalar();
TotalCreditLble.Text = "The total Credit :" + total.ToString();
答案 1 :(得分:4)
已经有一个与此命令关联的打开DataReader,必须先关闭它。
这就是你不共享命令的原因。代码中的某处你做到了:
cmd.ExecuteReader();
但您没有利用命令周围的using
语句,因为您想要共享它。你不能这样做。请参阅,ExecuteReader
在您一次读取一行时保持与服务器的连接;但是现在该命令被锁定,因为此时它是有状态的。正确的方法,总是,就是:
using (SqlConnection c = new SqlConnection(cString))
{
using (SqlCommand cmd = new SqlCommand(sql, c))
{
// inside of here you can use ExecuteReader
using (SqlDataReader rdr = cmd.ExecuteReader())
{
// use the reader
}
}
}
这些是非托管资源,需要谨慎处理。这就是为什么用using
包装它们是必要的。
不要共享这些对象。构建它们,打开它们,使用它们并处理它们。
通过利用using
,您将永远不必担心关闭和处理这些对象。
你的代码,写的有点不同:
var cs = ConfigurationManager.ConnectionStrings["MyDB"].ConnectionString;
var gridSql = "Select top 10 FirstName, LastName, Address, City, State from Customers";
var cntSql = "SELECT TOP 10 COUNT(CreditLimit) FROM Customers";
using (SqlConnection con = new SqlConnection(cs))
{
con.Open();
try
{
using (SqlCommand cmd = new SqlCommand(gridSql, con))
{
GridView1.DataSource = cmd.ExecuteReader();
GridView1.DataBind();
}
using (SqlCommand cmd = new SqlCommand(cntSql, con))
{
int total = (int)cmd.ExecuteScalar();
TotalCreditLble.Text = "The total Credit :" + total.ToString();
}
}
catch(Exception exp)
{
Response.Write(exp.Message);
}
}
答案 2 :(得分:0)
谢谢你,但对于那些谈论使用块的人来说! 为什么这段代码工作正常,我在视频上看到它的例子!使用相同的SqlCommand实例并通过使用方法CommanText和SqlCommand的相同实例传递不同的查询是一样的,它执行得很好,这是代码:
using (SqlConnection con = new SqlConnection(cs))
{
SqlCommand cmd = new SqlCommand();
cmd.Connection = con;
con.Open();
cmd.CommandText = "Delete from tbleProduct where ProductID= 4";
int TotalRowsAffected = cmd.ExecuteNonQuery();
Response.Write("Total rows affected :" + TotalRowsAffected );
cmd.CommandText = "Insert into tbleProduct values (4, 'Calculator', 100, 230)";
TotalRowsAffected = cmd.ExecuteNonQuery();
Response.Write("Total rows affected :" + TotalRowsAffected );
cmd.CommandText = "ypdate tbleProduct set QtyAvailbe = 234 where ProductID = 2";
TotalRowsAffected = cmd.ExecuteNonQuery();
Response.Write("Total rows affected :" + TotalRowsAffected );
}