C# 一个取消选择的行始终与dataGridView中的选定行一起插入到数据库中

C# 一个取消选择的行始终与dataGridView中的选定行一起插入到数据库中,c#,winforms,datagridview,datagridviewcheckboxcell,C#,Winforms,Datagridview,Datagridviewcheckboxcell,我制作了以下WinForm,用户在其中提供图书详细信息并创建图书记录。此书本记录将添加到dataGridView,并自动选中复选框: 现在,当我取消选择一些书籍并单击“插入到数据库”按钮将所选书籍插入到数据库时,其中一本取消选择的书籍总是与所选书籍一起插入到数据库中。这可能是任何一本被取消选择的书。就像这里我取消选择了一些书: public partial class CreateBookRecord : Form {

我制作了以下WinForm,用户在其中提供图书详细信息并创建图书记录。此书本记录将添加到dataGridView,并自动选中复选框:

现在,当我取消选择一些书籍并单击“插入到数据库”按钮将所选书籍插入到数据库时,其中一本取消选择的书籍总是与所选书籍一起插入到数据库中。这可能是任何一本被取消选择的书。
就像这里我取消选择了一些书:

    public partial class CreateBookRecord : Form
        {                
            DataTable addedBooks;
            DataColumn bookId, bookName, author, noOfCopies, noOfCopiesAvailable;
            DataGridViewCheckBoxColumn check;       
            public CreateBookRecord()
            {
                InitializeComponent();                   
            }

            private void CreateBookRecord_Load(object sender, EventArgs e)
            {
                check = new DataGridViewCheckBoxColumn(); //Create a checkbox column for DataGridView                   
                addedBooks = new DataTable();
                bookId = new DataColumn("Book ID", typeof(string));
                bookName = new DataColumn("Book Name", typeof(string));
                author = new DataColumn("Author", typeof(string));
                noOfCopies = new DataColumn("No of Copies", typeof(int));
                noOfCopiesAvailable = new DataColumn("No of Copies Available", typeof(int));
                addedBooks.Columns.AddRange(new DataColumn[] { bookId, bookName, author, noOfCopies,noOfCopiesAvailable });

                dataGridViewAddedBooks.Columns.Add(check); //To make first column as checkBox column
                dataGridViewAddedBooks.DataSource = addedBooks;
                dataGridViewAddedBooks.Columns["No of Copies Available"].Width = 0;
            }

            private void buttonCreateBook_Click(object sender, EventArgs e)
            {
                    try
                    {
                        addedBooks.Rows.Add(textBoxID.Text, textBoxBookName.Text, textBoxAuthorName.Text,Convert.ToInt32(textBoxNoOfCopies.Text),Convert.ToInt32(textBoxNoOfCopies.Text));                            
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }

            private void dataGridViewAddedBooks_RowsAdded(object sender, DataGridViewRowsAddedEventArgs e)
            {
                DataGridViewCheckBoxCell checkcell = (DataGridViewCheckBoxCell)dataGridViewAddedBooks.Rows[e.RowIndex].Cells[0];
                checkcell.Value = true;
            }

            private void buttonInsertBooks_Click(object sender, EventArgs e)
            {           
                foreach (DataGridViewRow row in dataGridViewAddedBooks.Rows)
                {
                    DataGridViewCheckBoxCell checkcell = (DataGridViewCheckBoxCell)row.Cells[0];
                    if (checkcell.Value == check.FalseValue)
                    {
                        dataGridViewAddedBooks.Rows.Remove(row);
                    }
                }
                SqlBulkCopy copy = new SqlBulkCopy(connection);
                copy.DestinationTableName = "Book";
                try
                {
                    connection.Open();
                    copy.WriteToServer(addedBooks);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                finally
                {
                    connection.Close();
                }        
            }

现在,当我单击“插入到数据库”按钮时,未选择的书籍将从dataGridView中删除,选定的书籍将插入到数据库:

现在,插入到数据库中的图书是选定的图书“123”、“345”、“678”以及一本未选定的图书“890”。这样,一本未选定的书总是与选定的书一起插入数据库。
我编写的代码是:

    public partial class CreateBookRecord : Form
        {                
            DataTable addedBooks;
            DataColumn bookId, bookName, author, noOfCopies, noOfCopiesAvailable;
            DataGridViewCheckBoxColumn check;       
            public CreateBookRecord()
            {
                InitializeComponent();                   
            }

            private void CreateBookRecord_Load(object sender, EventArgs e)
            {
                check = new DataGridViewCheckBoxColumn(); //Create a checkbox column for DataGridView                   
                addedBooks = new DataTable();
                bookId = new DataColumn("Book ID", typeof(string));
                bookName = new DataColumn("Book Name", typeof(string));
                author = new DataColumn("Author", typeof(string));
                noOfCopies = new DataColumn("No of Copies", typeof(int));
                noOfCopiesAvailable = new DataColumn("No of Copies Available", typeof(int));
                addedBooks.Columns.AddRange(new DataColumn[] { bookId, bookName, author, noOfCopies,noOfCopiesAvailable });

                dataGridViewAddedBooks.Columns.Add(check); //To make first column as checkBox column
                dataGridViewAddedBooks.DataSource = addedBooks;
                dataGridViewAddedBooks.Columns["No of Copies Available"].Width = 0;
            }

            private void buttonCreateBook_Click(object sender, EventArgs e)
            {
                    try
                    {
                        addedBooks.Rows.Add(textBoxID.Text, textBoxBookName.Text, textBoxAuthorName.Text,Convert.ToInt32(textBoxNoOfCopies.Text),Convert.ToInt32(textBoxNoOfCopies.Text));                            
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }

            private void dataGridViewAddedBooks_RowsAdded(object sender, DataGridViewRowsAddedEventArgs e)
            {
                DataGridViewCheckBoxCell checkcell = (DataGridViewCheckBoxCell)dataGridViewAddedBooks.Rows[e.RowIndex].Cells[0];
                checkcell.Value = true;
            }

            private void buttonInsertBooks_Click(object sender, EventArgs e)
            {           
                foreach (DataGridViewRow row in dataGridViewAddedBooks.Rows)
                {
                    DataGridViewCheckBoxCell checkcell = (DataGridViewCheckBoxCell)row.Cells[0];
                    if (checkcell.Value == check.FalseValue)
                    {
                        dataGridViewAddedBooks.Rows.Remove(row);
                    }
                }
                SqlBulkCopy copy = new SqlBulkCopy(connection);
                copy.DestinationTableName = "Book";
                try
                {
                    connection.Open();
                    copy.WriteToServer(addedBooks);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                finally
                {
                    connection.Close();
                }        
            }

如果有人能帮我解决这个问题,我将非常感激。
谢谢

我发现了这个问题。它位于以下代码中:

foreach (DataGridViewRow row in dataGridViewAddedBooks.Rows)
                {
                    DataGridViewCheckBoxCell checkcell = (DataGridViewCheckBoxCell)row.Cells[0];
                    if (checkcell.Value == check.FalseValue)
                    {
                        dataGridViewAddedBooks.Rows.Remove(row);
                    }
                }
当我们在DataGridView中循环并删除未选中的行时,会产生问题。
假设您在其中插入了三行,并取消选中了第一行和第二行。现在,当我们循环第一行时,我们发现一个未选中的行,它将从DataGridView中删除。DataGridView将在删除行时刷新自身。现在,第二行变为第一行。但是“row”计数器值现在将为1(开始时为0),它将检查缺少第一行的第二行(开始时为第二行)。因此它不会从dataGridView中删除,即使未检查也会更新到数据库中。

解决方案:

DataTable insertedBooks=new DataTable(); //We will use a new table to store all the cheched records
            insertedBooks = addedBooks.Clone();
            DataGridViewCheckBoxCell checkcell;
            foreach (DataGridViewRow row in dataGridViewAddedBooks.Rows)
            {               
                checkcell = (DataGridViewCheckBoxCell)row.Cells[0];
                if (checkcell.Value.Equals(true))
                {
                    insertedBooks.Rows.Add(row.Cells[1].Value.ToString(),row.Cells[2].Value.ToString(),row.Cells[3].Value.ToString(),Convert.ToInt32(row.Cells[4].Value),Convert.ToInt32(row.Cells[5].Value)); //Add all the checked records to insertedBooks table.
                }                           
            }            
            SqlBulkCopy copy = new SqlBulkCopy(connection);
            copy.DestinationTableName = "Book";
            connection.Open();
            copy.WriteToServer(insertedBooks); //Use insertedBooks table to copy records to database table.
            addedBooks.Clear(); //Delete all data from addedBooks table, it also cleard the DataGridView.