C#-数据读取器跳过第一个结果

问题描述 投票:0回答:2

希望看看我是否可以在这方面获得一些帮助。我有一个后台工作人员,它将执行SQL查询,然后在进度更改事件期间更新Datagrid。但是,它跳过第一行,并将重复的最后一行添加到数据网格。列标题已关闭,因为我在UID中添加了此列以进行故障排除。因此,请忽略标题与数据不匹配的方式。 enter image description here

我检查了在IF中具有Read()的常见原因,但事实并非如此。

有趣的是,如果我在阅读器上稍作休息= Sqlcmd.ExecuteReader();并逐步执行,它会随机运行。

任何帮助将不胜感激!我完全不知所措。

-

另外,如果我可以将DGV添加项从进度更改更改为完成事件,那也将是巨大的好处。 enter image description here

/// DO WORK
private void issueBWworker_DoWork_1(object sender, DoWorkEventArgs e)
        {
            // DGV 1
            RetriveTableData Obj = (RetriveTableData)e.Argument;
            string SqlcmdString = "SELECT * FROM xBETA_OAP_ISSUE";
            SqlDataReader reader;
            int i = 1;
            try
            {
                using (SqlConnection conn = new SqlConnection(ConnString))
                {
                    Sqlcmd = new SqlCommand(SqlcmdString, conn);
                    conn.Open();
                    reader = Sqlcmd.ExecuteReader();
                    if (reader.HasRows)
                    {
                        while (reader.Read())
                        {
                            Obj.uid = reader["id"].ToString();
                            Obj.iss_type = reader["issue_type"].ToString();
                            Obj.inc_num = reader["ticket_num"].ToString();
                            Obj.create_date = reader["create_date"].ToString();
                            Obj.created_by = reader["created_by"].ToString();
                            Obj.active = reader["active"].ToString();
                            Obj.change_date = reader["change_date"].ToString();
                            Obj.changed_by = reader["changed_by"].ToString();

                            Thread.Sleep(100);

                            //MessageBox.Show(Obj.uid);

                            // To Report progress.x
                            issueBWworker.ReportProgress(i, Obj);
                            if (issueBWworker.CancellationPending)
                            {
                                // Set the e.Cancel flag so that the WorkerCompleted event
                                // knows that the process was cancelled.
                                e.Cancel = true;
                                issueBWworker.ReportProgress(0);
                                return;
                            }
                            i++;
                        }
                        conn.Close();
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
/// Progress Changes

        private void issueBWworker_ProgressChanged_1(object sender, ProgressChangedEventArgs e)
        {
            if (!issueBWworker.CancellationPending)
            {
                // DGV 1
                RetriveTableData Obj = (RetriveTableData)e.UserState;
                issue_dgv.Rows.Add(Obj.uid.ToString(), Obj.iss_type.ToString(), Obj.inc_num.ToString(), Obj.create_date.ToString(), Obj.created_by.ToString(), Obj.active.ToString(), Obj.change_date.ToString(), Obj.changed_by.ToString());

                pbar.Value = e.ProgressPercentage;
                //toolStripStatusLabel1.Text = "Processing row.. " + e.ProgressPercentage.ToString() + " of " + TotalRecords;
            }
        }
/// Complete
        private void issueBWworker_RunWorkerCompleted_1(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Cancelled)
            {
                //toolStripStatusLabel1.Text = "Cancelled by User Intentionally...";
                pbar.Value = 0;
                pbar.Visible = false;
            }
            // Check to see if an error occurred in the background process.
            else if (e.Error != null)
            {
                //toolStripStatusLabel1.Text = e.Error.Message;
                pbar.Visible = false;
            }
            else
            {
                // BackGround Task Completed with out Error
                pbar.Visible = false;
                //toolStripStatusLabel1.Text = " All Records Loaded...";
            }
        }
c# sqldatareader
2个回答
2
投票

根据documentation,在备注部分中提到对ReportProgress的调用是异步的,并立即返回。但是,为了使其能够按预期与代码一起工作,您需要使其同步运行。

这是因为您使用相同的对象Obj,将阅读器的每次迭代中的数据传递给ReportProgress-并可能使用Thread.Sleep(100)作为同步手段-这实际上不是有效的或有效的设计,并可能导致您看到的行为。

例如,假设数据有四行,这将是结果:

+--------+-----------------------------------+--------------------------------------------+
| Thread | DoWork                            | ReportProgress                             |
+--------+-----------------------------------+--------------------------------------------+
| 1      | Populate values of Obj with row 1 |                                            |
+--------+-----------------------------------+--------------------------------------------+
| 2      | Wait 100 ms                       |                                            |
+--------+-----------------------------------+--------------------------------------------+
| 3      | Dispatch ReportProgress           |                                            |
+--------+-----------------------------------+--------------------------------------------+
| 4      | Populate values of Obj with row 2 |                                            |
+--------+-----------------------------------+--------------------------------------------+
| 5      | Wait 100 ms                       | Add a row with values of Obj, now at Row 2 |
+--------+-----------------------------------+--------------------------------------------+
| 6      | Dispatch ReportProgress           |                                            |
+--------+-----------------------------------+--------------------------------------------+
| 7      | Populate values of Obj with row 3 |                                            |
+--------+-----------------------------------+--------------------------------------------+
| 8      | Wait 100 ms                       | Add a row with values of Obj, now at Row 3 |
+--------+-----------------------------------+--------------------------------------------+
| 9      | Dispatch ReportProgress           |                                            |
+--------+-----------------------------------+--------------------------------------------+
| 10     | Populate values of Obj with row 4 |                                            |
+--------+-----------------------------------+--------------------------------------------+
| 11     | Wait 100 ms                       | Add a row with values of Obj, now at Row 4 |
+--------+-----------------------------------+--------------------------------------------+
| 12     | Dispatch ReportProgress           |                                            |
+--------+-----------------------------------+--------------------------------------------+
| 13     | End of iteration, no more rows    | Add a row with values of Obj, now at Row 4 |
+--------+-----------------------------------+--------------------------------------------+

0
投票

[从另一个站点,我发现了一些有用的东西。似乎reader.Read()可以跳过第一行。https://forums.asp.net/t/1124375.aspx?sqldatareader+reads+from+second+row+skip+the+first+row+https://bytes.com/topic/asp-net/answers/311487-sqldatareader-skipping-first-row-loop

    if ((reader.Read == false))
    {
        //do something here;
    }
    else
    {
        do
        {
            hinfo.Name = reader["_name"].ToString();
            hi.Add(hinfo);
        }
        while (reader.Read());
    }

从那篇文章看来,reader.Read()看着第一行,然后在第二行开始处理。我希望这有帮助。我有完全符合您原始要求的代码,并且正在使用FWIW。 (在这里Datareader not displaying first row接受)

© www.soinside.com 2019 - 2024. All rights reserved.