0

您好,我通过以下代码从 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.

你能帮我解决这个问题吗?

按照 Soner Gö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();
        }
4

5 回答 5

2

因为当你用你的 open 循环时SqlDataReader,已经有一个打开的连接。

DataReaders (ADO.NET)

“您可以使用 ADO.NET DataReader 从数据库中检索只读、只进的数据流。

结果在查询执行时返回,并存储在客户端的网络缓冲区中,直到您使用 DataReader 的 Read 方法请求它们”</p>

作为一般建议,使用usinglike;

using(SqlDataReader read= com.ExecuteReader())
{
    while (read.Read())
    {
       createLabelCmd((int)read["x"], (int)read["y"]);
    }
}

或者在你的连接字符串中设置它;

...MultipleActiveResultSets=true;
于 2013-10-08T08:11:48.627 回答
2

其他答案中概述了问题的原因(当 DataReader 打开时,该读取器使用的连接无法提供其他命令),但是许多人没有谈论针对这种情况引入的MultipleActiveResultSets

只需更改您的连接字符串以包含此选项,您的代码将无需任何更改即可工作

Server=yourServer;Database=yourDB;Trusted_Connection=True;MultipleActiveResultSets=true;

为了完成答案,MARS 从 SQL Server 2005 开始可用,您应该注意一些小问题。

于 2013-10-08T08:20:59.077 回答
1

我猜您正在编写一个坐着的计划者并尝试在特定位置显示标签。因此,您最好从klient给定事件的表中选择所有记录并将它们放在DataSet. 然后遍历它(使用 a foreach)并创建标签。这样,只有一个命令应该发送到数据库,显然,您的应用程序的性能会好得多。

话虽如此,我不明白你的sittingSearch变量是如何工作的,我认为它需要修改。

于 2013-10-08T08:19:05.630 回答
1

您可以为 createLabelCmd 使用第二个连接,也可以通过在连接字符串中添加“MultipleActiveResultSets=True”在初始连接中打开 MARS(多个活动结果集)。

http://msdn.microsoft.com/en-us/library/h32h3abf.aspx

于 2013-10-08T08:22:07.757 回答
0

将 MARS 设置为 True 并确保我使用了 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();
于 2017-08-01T14:40:04.023 回答