【问题标题】:InvalidOpearationException: There is already an open DataReaderInvalidOperationException:已经有一个打开的 DataReader
【发布时间】:2013-10-08 08:02:53
【问题描述】:

您好,我通过以下代码从 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();
        }

【问题讨论】:

  • @TimSchmelter 感谢这一点。我希望它不会影响打开 DataReader 的主要问题。
  • 我已经删除了我的评论,因为我注意到使用ExecuteScalar 选择多个列确实有效。 SqlCommand 似乎只选择了第一列。但是,这根本不是最佳做法。
  • 您在哪一行得到错误?
  • @Rezoan createLabelCmd((int)read["x"], (int)read["y"]);

标签: c# .net sql sql-server winforms


【解决方案1】:

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

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

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

为了完成答案,MARS 从 SQL Server 2005 和您应该知道的there are minor problems 开始可用。

【讨论】:

    【解决方案2】:

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

    来自DataReaders (ADO.NET)

    “您可以使用 ADO.NET DataReader 来检索一个只读的、 来自数据库的只进数据流。

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

    一般建议使用usinglike;

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

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

    ...MultipleActiveResultSets=true;
    

    【讨论】:

    • 我按照您的建议替换了我的代码部分(您可以在我的编辑中看到),但仍然得到相同的异常。你能帮帮我吗?
    【解决方案3】:

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

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

    【讨论】:

      【解决方案4】:

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

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

      【讨论】:

        【解决方案5】:

        将 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();
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-09-10
          • 2013-06-22
          • 2014-09-27
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多