C#学习笔记–foreach问题一
- 先上原代码看
- 原因分析
- 解决方法
- 最后
小编第一次在CSDN这个大舞台写博客。今天小编在上课的时候碰到个问题,就是C#窗体程序中,从用离线数据操作读取到数据在dataGridView1中时,用foreach对dataGridView1内数据进行修改时,发现会出现如果是连续的两行数据进行修改,会出现第二行数据修改不了的情况。
先上原代码看
首先是程序页代码
string readerid = skinComboBox1.SelectedValue.ToString();foreach(DataGridViewRow row in dataGridView1.Rows){if (row.Cells[0].Value != null){bis.BookLend((int)row.Cells[1].Value, readerid);}dataGridView2.DataSource = bis.showReaderLendInfo(readerid);}
接下来是类的代码
public void BookLend(int x,string readerid){DataRow[] bookRows = ds.Tables[\"TBookDetail\"].Select(\"bookId=\'\" + x + \"\'\");bookRows[0][\"Status\"] = \"借出\";DataRow LendRow = ds.Tables[\"TLendInfo\"].NewRow();LendRow[\"BookID\"] = x;LendRow[\"ReaderID\"] = readerid;LendRow[\"LendDate\"] = DateTime.Today;ds.Tables[\"TLendInfo\"].Rows.Add(LendRow);}public DataView showReaderLendInfo(string readerid){DataView dvLend = new DataView(ds.Tables[\"TLendInfo\"]);dvLend.RowFilter = \"ReaderID=\'\" + readerid + \"\'\";return dvLend;}
原因分析
原因在于foreach在检测到第一个打钩的项目后,它就把图书状态修改成“在库”和那个向TLendInfo表格添加数据同时进行了,所以会导致dataGridView1的数据在某一次foreach循环中都在刷新数据,所以读取到第一个打钩的行后,对那行进行操作,就导致表刷新,打钩行的下一行数据顶上来,而foreach却在下一行的位置,所以就导致会有读取不了的情况。
解决方法
方法一:用两个foreach将两个操作分开,使他们不同时进行
private void BookLend(){string readerID = cbbReaderSelect.SelectedValue.ToString();List<int> bookIdToLend=new List<int>();//获取选中的书籍ID号foreach(DataGridViewRow row in dgvBookList.Rows){if(row.Cells[\"ColSelect\"].Value!=null){int bookId=(int)row.Cells[1].Value;//将BookIdJ加入泛型列表bookIdToLend.Add(bookId);}}//对每一本书,做两个数据操作:改TBookDetail,加TLendInfoforeach(int bookId in bookIdToLend){DataRow[] bookRows=ds.Tables[\"TBookDetail\"].Select(\"bookId=\'\"+bookId+\"\'\");bookRows[0][\"Status\"] = \"借出\";DataRow LendRow = ds.Tables[\"TLendInfo\"].NewRow();LendRow[\"BookID\"] = bookId;LendRow[\"ReaderID\"] = readerID;LendRow[\"LendDate\"] = DateTime.Today;ds.Tables[\"TLendInfo\"].Rows.Add(LendRow);}}
方法二:运用goto去实现foreach的再循环(但会导致效率不高)
string readerid = skinComboBox1.SelectedValue.ToString();cc:foreach(DataGridViewRow row in dataGridView1.Rows){if (row.Cells[0].Value != null){bis.BookLend((int)row.Cells[1].Value, readerid);goto cc;}}dataGridView2.DataSource = bis.showReaderLendInfo(readerid);
方法三:不用foreach去循环,用for,控制循环遍历,就可以继续循环
for (int i = 0; i < dataGridView1.Rows.Count; i++ ){if (dataGridView1.Rows[i].Cells[0].Value != null){bis.BookLend((int)dataGridView1.Rows[i].Cells[1].Value , readerid);i--;}dataGridView2.DataSource = bis.showReaderLendInfo(readerid);}
最后
感谢所有来阅读的人,也希望各位大佬留下你们的意见,或者小弟哪里表达不明的,可以留言,我必回复!!!