您好我通过以下代码从SQL创建控件:
string query = "SELECT * FROM [schema] WHERE idSch=@id";
SqlCommand com = new SqlCommand(query, con);
com.Parameters.AddWithValue("@id", result);
con.Open();
SqlDataReader read= com.ExecuteReader();
while (read.Read())
{
createLabelCmd((int)read["x"], (int)read["y"]);
}
con.Close();
问题是createLabelCmd
包含SqlCommand
,需要开放SqlConnection
内部createLabelCmd
String ResultSitting
private void createLabelCmd(int x, int y)
{
for (int i = 0; i < 1; i++)
{
var newLabel = new Label();
newLabel.Location = new Point(x, y);
newLabel.Text = realpocsed.ToString();
string sitting = newLabel.Name;
string sittingSearch = (sitting).Substring(3, 1);
if (sittingSearch != null && kzajezdu == "kZajezdu")
{
string querySitting = "SELECT name, surname FROM klient WHERE sitting = @sitting AND event=@event AND year=@year";
SqlCommand cmdSitting = new SqlCommand(querySitting, spojeni);
cmdSitting.Parameters.AddWithValue("@sitting", sittingSearch);
cmdSitting.Parameters.AddWithValue("@event", idEvent);
cmdSitting.Parameters.AddWithValue("@year", klientClass.Year());
ResultSitting = cmdSitting.ExecuteScalar().ToString().Trim(); //This might be the issue
}
if (kzajezdu == "kZajezdu")
{
newLabel.MouseHover += delegate(object sender, EventArgs e)
{
ToolTip ToolTip1 = new ToolTip();
ToolTip1.ShowAlways = true;
if (sittingSearch != null)
{
ToolTip1.Show(ResultSitting, newLabel);
}
else { ToolTip1.Show("This sitting is Empty!", newLabel); }
};
}
panel1.Controls.Add(newLabel);
}
我得到一个例外:InvalidOpearationException: There is already an open DataReader associated with this Command which must be closed first.
请你帮我解决一下?
编辑为SonerGönül建议:
try
{
string query = "SELECT * FROM [schema] WHERE idSch=@id";
SqlCommand com = new SqlCommand(query, con);
com.Parameters.AddWithValue("@id", idSch);
con.Open();
SqlDataReader read= com.ExecuteReader();
while (precti.Read())
{
createLabelCmd((int)read["x"], (int)read["y"]);
}
con.Close();
}
答案 0 :(得分:2)
因为当您使用打开的SqlDataReader
进行循环时,已经有一个打开的连接。
“您可以使用ADO.NET DataReader检索只读, 来自数据库的仅向前流数据。
结果在查询执行时返回,并存储在 客户端上的网络缓冲区,直到您使用Read请求它们 DataReader的方法“
作为一般推荐,请使用using
之类的;
using(SqlDataReader read= com.ExecuteReader())
{
while (read.Read())
{
createLabelCmd((int)read["x"], (int)read["y"]);
}
}
或者在连接字符串中设置它;
...MultipleActiveResultSets=true;
答案 1 :(得分:2)
问题的原因在其他答案中有所概述(当DataReader打开时,该读取器使用的连接无法提供其他命令),但很多人都没有谈到为此类引入的MultipleActiveResultSets情况
只需更改连接字符串即可包含此选项,您的代码无需任何更改即可运行
Server=yourServer;Database=yourDB;Trusted_Connection=True;MultipleActiveResultSets=true;
要完成答案,可以从SQL Server 2005和there are minor problems开始提供MARS,您应该知道。
答案 2 :(得分:1)
我猜你正在写一个坐姿计划器并尝试在特定位置展示标签。因此,您最好从klient
表中选择给定事件的所有记录,并将它们放在DataSet
中。然后迭代它(使用foreach
)并创建标签。这样,只有一个命令应该发送到数据库,显然,应用程序的性能会更好。
话虽如此,我不明白你的sittingSearch
变量是如何工作的,我认为它需要修改。
答案 3 :(得分:1)
您可以在createLabelCmd中使用第二个连接,也可以在初始连接中启用MARS(多个活动结果集),方法是在连接字符串中添加“MultipleActiveResultSets = True”。
答案 4 :(得分:0)
将MARS设置为True AND 确保我使用ToList();在我的if语句和返回中 在下面的代码中,我在if语句的两个条件中都缺少toList(),我在发布后在IIS 8.5上收到错误。将语句更新到下面工作的@!
var varM = (id == 1) ? db.M.Where(x => x.UN== userID).ToList() : db.M.Where(x => x.EUN== userID).ToList();